@@ -23,16 +23,16 @@ export default function buildMultiexp(curve, groupName) {
2323
2424 let sGIn ;
2525 let fnName ;
26- if ( groupName == "G1" ) {
27- if ( inType == "affine" ) {
26+ if ( groupName === "G1" ) {
27+ if ( inType === "affine" ) {
2828 fnName = "g1m_multiexpAffine_chunk" ;
2929 sGIn = G . F . n8 * 2 ;
3030 } else {
3131 fnName = "g1m_multiexp_chunk" ;
3232 sGIn = G . F . n8 * 3 ;
3333 }
34- } else if ( groupName == "G2" ) {
35- if ( inType == "affine" ) {
34+ } else if ( groupName === "G2" ) {
35+ if ( inType === "affine" ) {
3636 fnName = "g2m_multiexpAffine_chunk" ;
3737 sGIn = G . F . n8 * 2 ;
3838 } else {
@@ -44,33 +44,30 @@ export default function buildMultiexp(curve, groupName) {
4444 }
4545 const nPoints = Math . floor ( buffBases . byteLength / sGIn ) ;
4646
47- if ( nPoints == 0 ) return G . zero ;
47+ if ( nPoints === 0 ) return G . zero ;
4848 const sScalar = Math . floor ( buffScalars . byteLength / nPoints ) ;
49- if ( sScalar * nPoints != buffScalars . byteLength ) {
49+ if ( sScalar * nPoints !== buffScalars . byteLength ) {
5050 throw new Error ( "Scalar size does not match" ) ;
5151 }
5252
5353 const bitChunkSize = pTSizes [ log2 ( nPoints ) ] ;
5454 const nChunks = Math . floor ( ( sScalar * 8 - 1 ) / bitChunkSize ) + 1 ;
5555
56- console . log ( "buffBases len" , buffBases . byteLength , "sGIn" , sGIn , "nPoints" , nPoints ) ;
57- console . log ( "buffScalars len" , buffScalars . byteLength , "sScalar" , sScalar ) ;
58- console . log ( "bitChunkSize" , bitChunkSize , "nChunks" , nChunks ) ;
5956
6057 const opPromises = [ ] ;
6158 for ( let i = 0 ; i < nChunks ; i ++ ) {
6259 const task = [
63- { cmd : "ALLOCSET" , var : 0 , buff : buffBases . buffer } ,
64- { cmd : "ALLOCSET" , var : 1 , buff : buffScalars . buffer } ,
60+ { cmd : "ALLOCSET" , var : 0 , buff : buffBases } ,
61+ { cmd : "ALLOCSET" , var : 1 , buff : buffScalars } ,
6562 { cmd : "ALLOC" , var : 2 , len : G . F . n8 * 3 } ,
6663 { cmd : "CALL" , fnName : fnName , params : [
67- { var : 0 } ,
68- { var : 1 } ,
69- { val : sScalar } ,
70- { val : nPoints } ,
71- { val : i * bitChunkSize } ,
72- { val : Math . min ( sScalar * 8 - i * bitChunkSize , bitChunkSize ) } ,
73- { var : 2 }
64+ { var : 0 } , //pBases
65+ { var : 1 } , // pScalars
66+ { val : sScalar } , // scalarSize
67+ { val : nPoints } , // nPoints
68+ { val : i * bitChunkSize } , // startBit
69+ { val : Math . min ( sScalar * 8 - i * bitChunkSize , bitChunkSize ) } , // chunkSize
70+ { var : 2 } // pr
7471 ] } ,
7572 { cmd : "GET" , out : 0 , var : 2 , len : G . F . n8 * 3 }
7673 ] ;
@@ -94,17 +91,17 @@ export default function buildMultiexp(curve, groupName) {
9491
9592 async function _multiExp ( buffBases , buffScalars , inType , logger , logText ) {
9693 const MAX_CHUNK_SIZE = 1 << 22 ;
97- const MIN_CHUNK_SIZE = 1 << 10 ;
94+ const MIN_CHUNK_SIZE = 1 << 15 ;
9895 let sGIn ;
9996
100- if ( groupName == "G1" ) {
101- if ( inType == "affine" ) {
97+ if ( groupName === "G1" ) {
98+ if ( inType === "affine" ) {
10299 sGIn = G . F . n8 * 2 ;
103100 } else {
104101 sGIn = G . F . n8 * 3 ;
105102 }
106- } else if ( groupName == "G2" ) {
107- if ( inType == "affine" ) {
103+ } else if ( groupName === "G2" ) {
104+ if ( inType === "affine" ) {
108105 sGIn = G . F . n8 * 2 ;
109106 } else {
110107 sGIn = G . F . n8 * 3 ;
@@ -114,50 +111,48 @@ export default function buildMultiexp(curve, groupName) {
114111 }
115112
116113 const nPoints = Math . floor ( buffBases . byteLength / sGIn ) ;
117- if ( nPoints == 0 ) return G . zero ;
114+ if ( nPoints === 0 ) return G . zero ;
118115 const sScalar = Math . floor ( buffScalars . byteLength / nPoints ) ;
119- if ( sScalar * nPoints != buffScalars . byteLength ) {
116+ if ( sScalar * nPoints !== buffScalars . byteLength ) {
120117 throw new Error ( "Scalar size does not match" ) ;
121118 }
122119
123120 console . log ( "buffBases.buffer instanceof SharedArrayBuffer" , buffBases . buffer instanceof SharedArrayBuffer ) ;
124121 console . log ( "buffScalars.buffer instanceof SharedArrayBuffer" , buffScalars . buffer instanceof SharedArrayBuffer ) ;
125122
123+ let result = [ ] ;
126124 const opPromises = [ ] ;
127- if ( buffBases . buffer
128- && ( buffBases . buffer instanceof SharedArrayBuffer )
129- && buffScalars . buffer
130- && ( buffScalars . buffer instanceof SharedArrayBuffer )
131- )
132- {
133- // If we are working with SharedArrayBuffers, we can do it in one chunk because memory is shared between threads
134- if ( logger ) logger . debug ( `Multiexp start: ${ logText } : ${ nPoints } ` ) ;
135- opPromises . push ( _multiExpChunk ( buffBases , buffScalars , inType , logger , logText ) . then ( ( r ) => {
136- if ( logger ) logger . debug ( `Multiexp end: ${ logText } : ${ nPoints } ` ) ;
137- return r ;
138- } ) ) ;
139- } else {
140- const bitChunkSize = pTSizes [ log2 ( nPoints ) ] ;
141- const nChunks = Math . floor ( ( sScalar * 8 - 1 ) / bitChunkSize ) + 1 ;
142-
143- let chunkSize ;
144- chunkSize = Math . floor ( nPoints / ( tm . concurrency / nChunks ) ) ;
145- if ( chunkSize > MAX_CHUNK_SIZE ) chunkSize = MAX_CHUNK_SIZE ;
146- if ( chunkSize < MIN_CHUNK_SIZE ) chunkSize = MIN_CHUNK_SIZE ;
147-
148- for ( let i = 0 ; i < nPoints ; i += chunkSize ) {
149- if ( logger ) logger . debug ( `Multiexp start: ${ logText } : ${ i } /${ nPoints } ` ) ;
150- const n = Math . min ( nPoints - i , chunkSize ) ;
151- const buffBasesChunk = buffBases . slice ( i * sGIn , ( i + n ) * sGIn ) ;
152- const buffScalarsChunk = buffScalars . slice ( i * sScalar , ( i + n ) * sScalar ) ;
153- opPromises . push ( _multiExpChunk ( buffBasesChunk , buffScalarsChunk , inType , logger , logText ) . then ( ( r ) => {
154- if ( logger ) logger . debug ( `Multiexp end: ${ logText } : ${ i } /${ nPoints } ` ) ;
155- return r ;
156- } ) ) ;
157- }
125+ const bitChunkSize = pTSizes [ log2 ( nPoints ) ] ;
126+ let nChunks = Math . floor ( ( sScalar * 8 - 1 ) / bitChunkSize ) + 1 ;
127+
128+ if ( groupName === "G2" ) {
129+ // G2 has bigger points, so we reduce chunk size to optimize memory usage
130+ nChunks *= 2 ;
158131 }
159132
160- const result = await Promise . all ( opPromises ) ;
133+ let chunkSize ;
134+ //chunkSize = Math.floor(nPoints / (tm.concurrency /nChunks));
135+ chunkSize = Math . floor ( nPoints / nChunks ) ;
136+ if ( chunkSize > MAX_CHUNK_SIZE ) chunkSize = MAX_CHUNK_SIZE ;
137+ if ( chunkSize < MIN_CHUNK_SIZE ) chunkSize = MIN_CHUNK_SIZE ;
138+
139+ for ( let i = 0 ; i < nPoints ; i += chunkSize ) {
140+ if ( logger ) logger . debug ( `Multiexp start: ${ logText } : ${ i } /${ nPoints } ` ) ;
141+ const n = Math . min ( nPoints - i , chunkSize ) ;
142+
143+ const buffBasesChunk = buffBases . slice ( i * sGIn , ( i + n ) * sGIn ) ;
144+ const buffScalarsChunk = buffScalars . slice ( i * sScalar , ( i + n ) * sScalar ) ;
145+
146+ // opPromises.push(_multiExpChunk(buffBasesChunk, buffScalarsChunk, inType, logger, logText).then((r) => {
147+ // if (logger) logger.debug(`Multiexp end: ${logText}: ${i}/${nPoints}`);
148+ // return r;
149+ // }));
150+ const r = await _multiExpChunk ( buffBasesChunk , buffScalarsChunk , inType , logger , logText ) ;
151+ if ( logger ) logger . debug ( `Multiexp end: ${ logText } : ${ i } /${ nPoints } ` ) ;
152+ result . push ( r ) ;
153+ }
154+
155+ //result = await Promise.all(opPromises);
161156
162157 let res = G . zero ;
163158 for ( let i = result . length - 1 ; i >= 0 ; i -- ) {
0 commit comments