import getRandomValues from './getRandomValues' ; import { CurveType , MCLBN_COMPILED_TIME_VAR , MCLBN_FP_SIZE , MCLBN_FR_SIZE , MCLBN_G1_SIZE , MCLBN_G2_SIZE , MCLBN_GT_SIZE } from './constants' ; const createModule = require ( './mcl_c.js' ) ; internal export let mod ; internal export const _malloc = ( size ) => { return mod . _mclBnMalloc ( size ) ; } ; internal export const _free = ( pos ) => { mod . _mclBnFree ( pos ) ; } ; export const ptrToAsciiStr = ( pos , n ) => { let s = '' ; for ( let i = 0 ; i < n ; i ++ ) { s += String . fromCharCode ( mod . HEAP8 [ pos + i ] ) ; } return s ; } ; export const asciiStrToPtr = ( pos , s ) => { for ( let i = 0 ; i < s . length ; i ++ ) { mod . HEAP8 [ pos + i ] = s . charCodeAt ( i ) ; } } ; export const toHex = ( a , start , n ) => { let s = '' ; for ( let i = 0 ; i < n ; i ++ ) { s += ( '0' + a [ start + i ] . toString ( 16 ) ) . slice ( - 2 ) ; } return s ; } ; export const toHexStr = ( a ) => { return toHex ( a , 0 , a . length ) ; } ; export const fromHexStr = ( s ) => { if ( s . length & 1 ) throw new Error ( 'fromHexStr:length must be even ' + s . length ) ; const n = s . length / 2 ; const a = new Uint8Array ( n ) ; for ( let i = 0 ; i < n ; i ++ ) { a [ i ] = parseInt ( s . slice ( i * 2 , i * 2 + 2 ) , 16 ) ; } return a ; } ; export const free = ( x ) => { _free ( x ) ; } ; const addWrappedMethods = ( ) => { type StringReader = ( pos : number , maxBufSize : number , x : number , ioMode : number ) => number ; const _wrapGetStr = ( func , returnAsStr = true ) => { return ( x , ioMode = 0 ) => { const maxBufSize = 3096 ; const pos = _malloc ( maxBufSize ) ; const n = func ( pos , maxBufSize , x , ioMode ) ; if ( n <= 0 ) { throw new Error ( 'err gen_str:' + x ) ; } let s = null ; if ( returnAsStr ) { s = ptrToAsciiStr ( pos , n ) ; } else { s = new Uint8Array ( mod . HEAP8 . subarray ( pos , pos + n ) ) ; } _free ( pos ) ; return s ; } ; } ; const _wrapSerialize = ( func ) => { return _wrapGetStr ( func , false ) ; } ; type StringWriter = ( pos : number , maxBufSize : number , x : number ) => number ; const _wrapDeserialize = ( func ) => { return ( x , buf ) => { const pos = _malloc ( buf . length ) ; mod . HEAP8 . set ( buf , pos ) ; const r = func ( x , pos , buf . length ) ; _free ( pos ) ; if ( r === 0 || r !== buf . length ) throw new Error ( `err _wrapDeserialize: ${ r } != ${ buf . length }` ) ; } ; } ; const _wrapInput = ( func , argNum ) => { return function ( ... args ) { const buf = args [ argNum ] ; const typeStr = Object . prototype . toString . apply ( buf ) ; if ( ! [ '[object String]' , '[object Uint8Array]' , '[object Array]' ] . includes ( typeStr ) ) { throw new Error ( `err bad type:"${ typeStr }". Use String or Uint8Array.` ) ; } const ioMode = args [ argNum + 1 ] ; const pos = _malloc ( buf . length ) ; if ( typeStr === '[object String]' ) { asciiStrToPtr ( pos , buf ) ; } else { mod . HEAP8 . set ( buf , pos ) ; } const r = func ( ... args . slice ( 0 , argNum ) , pos , buf . length , ioMode ) ; _free ( pos ) ; if ( r ) throw new Error ( 'err _wrapInput ' + buf ) ; } ; } ; mod . mclBnFr_malloc = ( ) => { return _malloc ( MCLBN_FR_SIZE ) ; } ; mod . mclBnFr_setLittleEndian = _wrapInput ( mod . _mclBnFr_setLittleEndian , 1 ) ; mod . mclBnFr_setLittleEndianMod = _wrapInput ( mod . _mclBnFr_setLittleEndianMod , 1 ) ; mod . mclBnFr_setBigEndianMod = _wrapInput ( mod . _mclBnFr_setBigEndianMod , 1 ) ; mod . mclBnFr_setStr = _wrapInput ( mod . _mclBnFr_setStr , 1 ) ; mod . mclBnFr_getStr = _wrapGetStr ( mod . _mclBnFr_getStr ) ; mod . mclBnFr_deserialize = _wrapDeserialize ( mod . _mclBnFr_deserialize ) ; mod . mclBnFr_serialize = _wrapSerialize ( mod . _mclBnFr_serialize ) ; mod . mclBnFr_setHashOf = _wrapInput ( mod . _mclBnFr_setHashOf , 1 ) ; mod . mclBnFp_malloc = ( ) => { return _malloc ( MCLBN_FP_SIZE ) ; } ; mod . mclBnFp_setLittleEndian = _wrapInput ( mod . _mclBnFp_setLittleEndian , 1 ) ; mod . mclBnFp_setLittleEndianMod = _wrapInput ( mod . _mclBnFp_setLittleEndianMod , 1 ) ; mod . mclBnFp_setBigEndianMod = _wrapInput ( mod . _mclBnFp_setBigEndianMod , 1 ) ; mod . mclBnFp_setStr = _wrapInput ( mod . _mclBnFp_setStr , 1 ) ; mod . mclBnFp_getStr = _wrapGetStr ( mod . _mclBnFp_getStr ) ; mod . mclBnFp_deserialize = _wrapDeserialize ( mod . _mclBnFp_deserialize ) ; mod . mclBnFp_serialize = _wrapSerialize ( mod . _mclBnFp_serialize ) ; mod . mclBnFp_setHashOf = _wrapInput ( mod . _mclBnFp_setHashOf , 1 ) ; mod . mclBnFp2_malloc = ( ) => { return _malloc ( MCLBN_FP_SIZE * 2 ) ; } ; mod . mclBnFp2_deserialize = _wrapDeserialize ( mod . _mclBnFp2_deserialize ) ; mod . mclBnFp2_serialize = _wrapSerialize ( mod . _mclBnFp2_serialize ) ; mod . mclBnG1_malloc = ( ) => { return _malloc ( MCLBN_G1_SIZE ) ; } ; mod . mclBnG1_setStr = _wrapInput ( mod . _mclBnG1_setStr , 1 ) ; mod . mclBnG1_getStr = _wrapGetStr ( mod . _mclBnG1_getStr ) ; mod . mclBnG1_deserialize = _wrapDeserialize ( mod . _mclBnG1_deserialize ) ; mod . mclBnG1_serialize = _wrapSerialize ( mod . _mclBnG1_serialize ) ; mod . mclBnG1_hashAndMapTo = _wrapInput ( mod . _mclBnG1_hashAndMapTo , 1 ) ; mod . mclBnG2_malloc = ( ) => { return _malloc ( MCLBN_G2_SIZE ) ; } ; mod . mclBnG2_setStr = _wrapInput ( mod . _mclBnG2_setStr , 1 ) ; mod . mclBnG2_getStr = _wrapGetStr ( mod . _mclBnG2_getStr ) ; mod . mclBnG2_deserialize = _wrapDeserialize ( mod . _mclBnG2_deserialize ) ; mod . mclBnG2_serialize = _wrapSerialize ( mod . _mclBnG2_serialize ) ; mod . mclBnG2_hashAndMapTo = _wrapInput ( mod . _mclBnG2_hashAndMapTo , 1 ) ; mod . mclBnGT_malloc = ( ) => { return _malloc ( MCLBN_GT_SIZE ) ; } ; mod . mclBnGT_deserialize = _wrapDeserialize ( mod . _mclBnGT_deserialize ) ; mod . mclBnGT_serialize = _wrapSerialize ( mod . _mclBnGT_serialize ) ; mod . mclBnGT_setStr = _wrapInput ( mod . _mclBnGT_setStr , 1 ) ; mod . mclBnGT_getStr = _wrapGetStr ( mod . _mclBnGT_getStr ) ; } ; /** given `CurveType` of last `initializeMcl` call */ export let initializedCurveType ; export const initializeMcl = async ( curveType = CurveType . BN254 ) => { mod = await createModule ( { cryptoGetRandomValues : ( p , n ) => { const a = new Uint8Array ( n ) ; getRandomValues ( a ) ; for ( let i = 0 ; i < n ; i ++ ) { mod . HEAP8 [ p + i ] = a [ i ] ; } } } ) ; initializedCurveType = curveType ; addWrappedMethods ( ) ; const r = mod . _mclBn_init ( curveType , MCLBN_COMPILED_TIME_VAR ) ; if ( r ) throw new Error ( '_mclBn_init err ' + r ) ; } ;