@@ -80,12 +80,30 @@ export class Signature {
8080 /**
8181 * The ``s`` value for a signature.
8282 */
83- get s ( ) : string { return this . #s; }
83+ get s ( ) : string {
84+ assertArgument ( parseInt ( this . #s. substring ( 0 , 3 ) ) < 8 , "non-canonical s; use ._s" , "s" , this . #s) ;
85+ return this . #s;
86+ }
8487 set s ( _value : BytesLike ) {
8588 assertArgument ( dataLength ( _value ) === 32 , "invalid s" , "value" , _value ) ;
86- const value = hexlify ( _value ) ;
87- assertArgument ( parseInt ( value . substring ( 0 , 3 ) ) < 8 , "non-canonical s" , "value" , value ) ;
88- this . #s = value ;
89+ this . #s = hexlify ( _value ) ;
90+ }
91+
92+ /**
93+ * Return the s value, unchecked for EIP-2 compliance.
94+ *
95+ * This should generally not be used and is for situations where
96+ * a non-canonical S value might be relevant, such as Frontier blocks
97+ * that were mined prior to EIP-2 or invalid Authorization List
98+ * signatures.
99+ */
100+ get _s ( ) : string { return this . #s; }
101+
102+ /**
103+ * Returns true if the Signature is valid for [[link-eip-2]] signatures.
104+ */
105+ isValid ( ) : boolean {
106+ return ( parseInt ( this . #s. substring ( 0 , 3 ) ) < 8 ) ;
89107 }
90108
91109 /**
@@ -167,14 +185,14 @@ export class Signature {
167185 }
168186
169187 [ Symbol . for ( 'nodejs.util.inspect.custom' ) ] ( ) : string {
170- return `Signature { r: "${ this . r } ", s: "${ this . s } ", yParity: ${ this . yParity } , networkV: ${ this . networkV } }` ;
188+ return `Signature { r: "${ this . r } ", s: "${ this . _s } "${ this . isValid ( ) ? "" : ', valid: "false"' } , yParity: ${ this . yParity } , networkV: ${ this . networkV } }` ;
171189 }
172190
173191 /**
174192 * Returns a new identical [[Signature]].
175193 */
176194 clone ( ) : Signature {
177- const clone = new Signature ( _guard , this . r , this . s , this . v ) ;
195+ const clone = new Signature ( _guard , this . r , this . _s , this . v ) ;
178196 if ( this . networkV ) { clone . #networkV = this . networkV ; }
179197 return clone ;
180198 }
@@ -187,7 +205,7 @@ export class Signature {
187205 return {
188206 _type : "signature" ,
189207 networkV : ( ( networkV != null ) ? networkV . toString ( ) : null ) ,
190- r : this . r , s : this . s , v : this . v ,
208+ r : this . r , s : this . _s , v : this . v ,
191209 } ;
192210 }
193211
@@ -293,10 +311,9 @@ export class Signature {
293311
294312 if ( bytes . length === 65 ) {
295313 const r = hexlify ( bytes . slice ( 0 , 32 ) ) ;
296- const s = bytes . slice ( 32 , 64 ) ;
297- assertError ( ( s [ 0 ] & 0x80 ) === 0 , "non-canonical s" ) ;
314+ const s = hexlify ( bytes . slice ( 32 , 64 ) ) ;
298315 const v = Signature . getNormalizedV ( bytes [ 64 ] ) ;
299- return new Signature ( _guard , r , hexlify ( s ) , v ) ;
316+ return new Signature ( _guard , r , s , v ) ;
300317 }
301318
302319 assertError ( false , "invalid raw signature length" ) ;
@@ -322,7 +339,6 @@ export class Signature {
322339
323340 assertError ( false , "missing s" ) ;
324341 } ) ( sig . s , sig . yParityAndS ) ;
325- assertError ( ( getBytes ( s ) [ 0 ] & 0x80 ) == 0 , "non-canonical s" ) ;
326342
327343 // Get v; by any means necessary (we check consistency below)
328344 const { networkV, v } = ( function ( _v ?: BigNumberish , yParityAndS ?: string , yParity ?: Numeric ) : { networkV ?: bigint , v : 27 | 28 } {
@@ -360,4 +376,3 @@ export class Signature {
360376 return result ;
361377 }
362378}
363-
0 commit comments