@@ -79,13 +79,15 @@ export class Signature implements ABISerializableObject {
7979 }
8080
8181 const type = KeyType . from ( parts [ 1 ] ) ;
82- // 65 for ECDSA, 64 for ED
82+ // 65 for all wire-format curves (we now pad ED to 65 bytes)
8383 const size =
84- type === KeyType . K1 || type === KeyType . R1 || type === KeyType . EM
84+ ( type === KeyType . K1 ||
85+ type === KeyType . R1 ||
86+ type === KeyType . EM ||
87+ type === KeyType . ED )
8588 ? 65
86- : type === KeyType . ED
87- ? 64
88- : undefined ;
89+ : undefined ;
90+
8991 const data = Base58 . decodeRipemd160Check ( parts [ 2 ] , size , type ) ;
9092 return new Signature ( type , data ) ;
9193 }
@@ -105,9 +107,8 @@ export class Signature implements ABISerializableObject {
105107 return new Signature ( KeyType . WA , data ) ;
106108 }
107109
108- // read 64 bytes for ED, 65 for everything else
109- const len = type === KeyType . ED ? 64 : 65 ;
110- return new Signature ( type , new Bytes ( decoder . readArray ( len ) ) ) ;
110+ const length = 65 ;
111+ return new Signature ( type , new Bytes ( decoder . readArray ( length ) ) ) ;
111112 }
112113
113114 /**
@@ -121,38 +122,6 @@ export class Signature implements ABISerializableObject {
121122 const h = hexStr . startsWith ( '0x' ) ? hexStr . slice ( 2 ) : hexStr ;
122123 const raw = Uint8Array . from ( Buffer . from ( h , 'hex' ) ) ;
123124 return Signature . fromRaw ( raw , type ) ;
124-
125- // const h = hexStr.startsWith('0x') ? hexStr.slice(2) : hexStr;
126-
127- // if (type === KeyType.ED) {
128- // if (h.length !== 128) {
129- // throw new Error(`ED25519 hex must be 128 chars, got ${h.length}`);
130- // }
131-
132- // // decode all 64 bytes at once
133- // const raw = Uint8Array.from(Buffer.from(h, 'hex'));
134- // return new Signature(KeyType.ED, new Bytes(raw));
135- // }
136-
137- // // non-ED: expect 65 bytes → 130 hex chars
138- // if (h.length !== 130) {
139- // throw new Error(`ECDSA/EM hex must be 130 chars, got ${h.length}`);
140- // }
141-
142- // const buf = Uint8Array.from(Buffer.from(h, 'hex'));
143- // // split off r, s, v
144- // const r = buf.slice(0, 32);
145- // const s = buf.slice(32, 64);
146- // let recid = buf[64];
147- // // Ethereum v (27/28) → wire recid (31/32) = v + 4
148- // recid += 4;
149-
150- // const arr = new Uint8Array(1 + 32 + 32);
151- // arr[0] = recid;
152- // arr.set(r, 1);
153- // arr.set(s, 33);
154-
155- // return new Signature(type, new Bytes(arr));
156125 }
157126
158127 /**
@@ -164,7 +133,11 @@ export class Signature implements ABISerializableObject {
164133 // ED25519: the raw is already [r‖s]
165134 if ( type === KeyType . ED ) {
166135 if ( raw . length !== 64 ) throw new Error ( `ED raw sig must be 64 bytes, got ${ raw . length } ` ) ;
167- return new Signature ( type , new Bytes ( raw ) ) ;
136+ // ► pad to 65 bytes with a zero at the end:
137+ const wire = new Uint8Array ( 65 ) ;
138+ wire . set ( raw , 0 ) ;
139+ wire [ 64 ] = 0 ;
140+ return new Signature ( type , new Bytes ( wire ) ) ;
168141 }
169142
170143 // ECDSA/EIP-191: raw should be 65 bytes [r‖s‖v]
@@ -204,8 +177,35 @@ export class Signature implements ABISerializableObject {
204177 * - ED: 64 bytes `[r(32)‖s(32)]`
205178 */
206179 constructor ( type : KeyType , data : Bytes | Uint8Array ) {
180+ let wire : Uint8Array ;
181+
182+ if ( type === KeyType . ED ) {
183+ const arr = data instanceof Bytes ? data . array : data ;
184+
185+ if ( arr . length === 64 ) {
186+ // pad to 65 so toString() and from() agree
187+ wire = new Uint8Array ( 65 ) ;
188+ wire . set ( arr , 0 ) ;
189+ wire [ 64 ] = 0 ;
190+ } else if ( arr . length === 65 ) {
191+ // already padded
192+ wire = arr ;
193+ } else {
194+ throw new Error ( `ED signature must be 64 or 65 bytes, got ${ arr . length } ` ) ;
195+ }
196+ } else {
197+ // everything else: expect exactly 65 bytes already in wire-format
198+ const arr = data instanceof Bytes ? data . array : data ;
199+
200+ if ( arr . length !== 65 ) {
201+ throw new Error ( `Expected 65-byte wire format for ${ type } , got ${ arr . length } ` ) ;
202+ }
203+
204+ wire = arr ;
205+ }
206+
207207 this . type = type ;
208- this . data = data instanceof Bytes ? data : new Bytes ( data ) ;
208+ this . data = new Bytes ( wire ) ;
209209 }
210210
211211 equals ( other : SignatureType ) : boolean {
@@ -251,9 +251,11 @@ export class Signature implements ABISerializableObject {
251251 const rawMsg = Bytes . from ( message ) . array ;
252252
253253 switch ( this . type ) {
254- case KeyType . ED :
255- // ED25519: raw `[r‖s]`
256- return Crypto . verify ( this . data . array , rawMsg , publicKey . data . array , this . type ) ;
254+ case KeyType . ED : {
255+ // ED25519: storage is [r||s||0], TweetNaCl needs exactly 64 bytes [r||s] - strip padded 0
256+ const sig64 = this . data . array . subarray ( 0 , 64 ) ;
257+ return Crypto . verify ( sig64 , rawMsg , publicKey . data . array , this . type ) ;
258+ }
257259
258260 case KeyType . EM : {
259261 // 1) unwrap wire [vWire‖r‖s]
0 commit comments