@@ -79,7 +79,7 @@ const abytes = (value: Bytes, length?: number, title: string = ''): Bytes => {
7979 return value ;
8080} ;
8181/** create Uint8Array */
82- const u8n = ( len : number ) : Uint8Array => new Uint8Array ( len ) ;
82+ const u8n = ( len : number ) : Bytes => new Uint8Array ( len ) ;
8383const padh = ( n : number | bigint , pad : number ) => n . toString ( 16 ) . padStart ( pad , '0' ) ;
8484const bytesToHex = ( b : Bytes ) : string =>
8585 Array . from ( abytes ( b ) )
@@ -162,15 +162,15 @@ export type AffinePoint = {
162162
163163/** secp256k1 formula. Koblitz curves are subclass of weierstrass curves with a=0, making it x³+b */
164164const koblitz = ( x : bigint ) => M ( M ( x * x ) * x + _b ) ;
165- /** assert is field element, including 0 */
165+ /** assert is element of field mod P (incl. 0) */
166166const FpIsValid = ( n : bigint ) => arange ( n , 0n , P ) ;
167- /** assert is field element and not 0 */
167+ /** assert is element of field mod P (excl. 0) */
168168const FpIsValidNot0 = ( n : bigint ) => arange ( n , 1n , P ) ;
169- /** assert is group elem */
169+ /** assert is element of field mod N (excl. 0) */
170170const FnIsValidNot0 = ( n : bigint ) => arange ( n , 1n , N ) ;
171171const isEven = ( y : bigint ) => ( y & 1n ) === 0n ;
172172/** create Uint8Array of byte n */
173- const u8of = ( n : number ) => Uint8Array . of ( n ) ;
173+ const u8of = ( n : number ) : Bytes => Uint8Array . of ( n ) ;
174174const getPrefix = ( y : bigint ) => u8of ( isEven ( y ) ? 0x02 : 0x03 ) ;
175175/** lift_x from BIP340 calculates square root. Validates x, then validates root*root. */
176176const lift_x = ( x : bigint ) => {
@@ -559,10 +559,10 @@ const hashes = {
559559 sha256 : undefined as undefined | ( ( message : Bytes ) => Bytes ) ,
560560} ;
561561
562- const callPrehash = ( asynchronous : boolean , message : Bytes , opts : { prehash ? : boolean } ) => {
563- abytes ( message , undefined , 'message' ) ;
564- if ( ! opts . prehash ) return message ;
565- return asynchronous ? hashes . sha256Async ( message ) : callHash ( 'sha256' ) ( message ) ;
562+ const prepMsg = ( msg : Bytes , opts : ECDSARecoverOpts , async_ : boolean ) : Bytes | Promise < Bytes > => {
563+ abytes ( msg , undefined , 'message' ) ;
564+ if ( ! opts . prehash ) return msg ;
565+ return async_ ? hashes . sha256Async ( msg ) : callHash ( 'sha256' ) ( msg ) ;
566566} ;
567567
568568type Pred < T > = ( v : Bytes ) => T | undefined ;
@@ -572,7 +572,7 @@ const byte1 = u8of(0x01);
572572const _maxDrbgIters = 1000 ;
573573const _drbgErr = 'drbg: tried max amount of iterations' ;
574574// HMAC-DRBG from NIST 800-90. Minimal, non-full-spec - used for RFC6979 signatures.
575- const hmacDrbg = < T > ( seed : Bytes , pred : Pred < T > ) : T => {
575+ const hmacDrbg = ( seed : Bytes , pred : Pred < Bytes > ) : Bytes => {
576576 let v = u8n ( L ) ; // Steps B, C of RFC6979 3.2: set hashLen
577577 let k = u8n ( L ) ; // In our case, it's always equal to L
578578 let i = 0 ; // Iterations counter, will throw when over max
@@ -598,13 +598,14 @@ const hmacDrbg = <T>(seed: Bytes, pred: Pred<T>): T => {
598598 } ;
599599 reset ( ) ;
600600 reseed ( seed ) ; // Steps D-G
601- let res : T | undefined = undefined ; // Step H: grind until k is in [1..n-1]
601+ let res : Bytes | undefined = undefined ; // Step H: grind until k is in [1..n-1]
602602 while ( ! ( res = pred ( gen ( ) ) ) ) reseed ( ) ; // test predicate until it returns ok
603603 reset ( ) ;
604604 return res ! ;
605605} ;
606606
607- const hmacDrbgAsync = async < T > ( seed : Bytes , pred : Pred < T > ) : Promise < T > => {
607+ // Identical to hmacDrbg, but async: uses built-in WebCrypto
608+ const hmacDrbgAsync = async ( seed : Bytes , pred : Pred < Bytes > ) : Promise < Bytes > => {
608609 let v = u8n ( L ) ; // Steps B, C of RFC6979 3.2: set hashLen
609610 let k = u8n ( L ) ; // In our case, it's always equal to L
610611 let i = 0 ; // Iterations counter, will throw when over max
@@ -630,7 +631,7 @@ const hmacDrbgAsync = async <T>(seed: Bytes, pred: Pred<T>): Promise<T> => {
630631 } ;
631632 reset ( ) ;
632633 await reseed ( seed ) ; // Steps D-G
633- let res : T | undefined = undefined ; // Step H: grind until k is in [1..n-1]
634+ let res : Bytes | undefined = undefined ; // Step H: grind until k is in [1..n-1]
634635 while ( ! ( res = pred ( await gen ( ) ) ) ) await reseed ( ) ; // test predicate until it returns ok
635636 reset ( ) ;
636637 return res ! ;
@@ -739,7 +740,7 @@ const setDefaults = (opts: ECDSASignOpts): Required<ECDSASignOpts> => {
739740 */
740741const sign = ( message : Bytes , secretKey : Bytes , opts : ECDSASignOpts = { } ) : Bytes => {
741742 opts = setDefaults ( opts ) ;
742- message = callPrehash ( false , message , opts ) ;
743+ message = prepMsg ( message , opts , false ) as Bytes ;
743744 return _sign ( message , secretKey , opts , hmacDrbg ) ;
744745} ;
745746
@@ -762,15 +763,15 @@ const signAsync = async (
762763 opts : ECDSASignOpts = { }
763764) : Promise < Bytes > => {
764765 opts = setDefaults ( opts ) ;
765- message = await callPrehash ( true , message , opts ) ;
766+ message = await prepMsg ( message , opts , true ) ;
766767 return _sign ( message , secretKey , opts , hmacDrbgAsync ) ;
767768} ;
768769
769770/**
770771 * Verify a signature using secp256k1. Sync: uses `hashes.sha256` and `hashes.hmacSha256`.
771- * @param signature - signature, default is 64-byte " compact" format
772- * @param message - message which has been signed
773- * @param publicKey - public key
772+ * @param signature - default is 64-byte ' compact' format, also see { @link ECDSASignatureFormat}
773+ * @param message - message which was signed. Keep in mind `prehash` from opts.
774+ * @param publicKey - public key which
774775 * @param opts - see {@link ECDSAVerifyOpts} for details.
775776 * @example
776777 * ```js
@@ -788,15 +789,15 @@ const verify = (
788789 opts : ECDSAVerifyOpts = { }
789790) : boolean => {
790791 opts = setDefaults ( opts ) ;
791- message = callPrehash ( false , message , opts ) ;
792+ message = prepMsg ( message , opts , false ) as Bytes ;
792793 return _verify ( signature , message , publicKey , opts ) ;
793794} ;
794795
795796/**
796797 * Verify a signature using secp256k1. Async: uses built-in WebCrypto hashes.
797- * @param signature - signature, default is 64-byte " compact" format
798- * @param message - message which has been signed
799- * @param publicKey - public key
798+ * @param signature - default is 64-byte ' compact' format, also see { @link ECDSASignatureFormat}
799+ * @param message - message which was signed. Keep in mind `prehash` from opts.
800+ * @param publicKey - public key which
800801 * @param opts - see {@link ECDSAVerifyOpts} for details.
801802 * @example
802803 * ```js
@@ -814,7 +815,7 @@ const verifyAsync = async (
814815 opts : ECDSAVerifyOpts = { }
815816) : Promise < boolean > => {
816817 opts = setDefaults ( opts ) ;
817- message = await callPrehash ( true , message , opts ) ;
818+ message = await prepMsg ( message , opts , true ) ;
818819 return _verify ( sig , message , publicKey , opts ) ;
819820} ;
820821
@@ -842,7 +843,7 @@ const _recover = (signature: Bytes, messageHash: Bytes) => {
842843 * Follows [SEC1](https://secg.org/sec1-v2.pdf) 4.1.6.
843844 */
844845const recoverPublicKey = ( signature : Bytes , message : Bytes , opts : ECDSARecoverOpts = { } ) : Bytes => {
845- message = callPrehash ( false , message , setDefaults ( opts ) ) ;
846+ message = prepMsg ( message , setDefaults ( opts ) , false ) as Bytes ;
846847 return _recover ( signature , message ) ;
847848} ;
848849
@@ -851,7 +852,7 @@ const recoverPublicKeyAsync = async (
851852 message : Bytes ,
852853 opts : ECDSARecoverOpts = { }
853854) : Promise < Bytes > => {
854- message = await callPrehash ( true , message , setDefaults ( opts ) ) ;
855+ message = await prepMsg ( message , setDefaults ( opts ) , true ) ;
855856 return _recover ( signature , message ) ;
856857} ;
857858
@@ -1166,5 +1167,6 @@ export {
11661167 Signature ,
11671168 utils ,
11681169 verify ,
1169- verifyAsync ,
1170+ verifyAsync
11701171} ;
1172+
0 commit comments