Mercurial > hg > ucis.core
comparison NaCl/APIv2.cs @ 73:6aca18ee4ec6
NaCl: improved ed25519 implementation, added simple API for ed25519 and sha512
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Sat, 02 Nov 2013 16:01:09 +0100 |
parents | 29cf42a12c34 |
children | 4714531734b3 |
comparison
equal
deleted
inserted
replaced
72:b7d981ccd434 | 73:6aca18ee4ec6 |
---|---|
2 using System.Globalization; | 2 using System.Globalization; |
3 using UCIS.Util; | 3 using UCIS.Util; |
4 using curve25519xsalsa20poly1305impl = UCIS.NaCl.crypto_box.curve25519xsalsa20poly1305; | 4 using curve25519xsalsa20poly1305impl = UCIS.NaCl.crypto_box.curve25519xsalsa20poly1305; |
5 using edwards25519sha512batchimpl = UCIS.NaCl.crypto_sign.edwards25519sha512batch; | 5 using edwards25519sha512batchimpl = UCIS.NaCl.crypto_sign.edwards25519sha512batch; |
6 using xsalsa20poly1305impl = UCIS.NaCl.crypto_secretbox.xsalsa20poly1305; | 6 using xsalsa20poly1305impl = UCIS.NaCl.crypto_secretbox.xsalsa20poly1305; |
7 using sha512impl = UCIS.NaCl.crypto_hash.sha512; | |
8 using ed25519impl = UCIS.NaCl.crypto_sign.ed25519; | |
7 | 9 |
8 namespace UCIS.NaCl.v2 { | 10 namespace UCIS.NaCl.v2 { |
9 public class curve25519keypair { | 11 public class curve25519keypair { |
10 private Byte[] secretkey; | 12 private Byte[] secretkey; |
11 private Byte[] publickey = null; | 13 private Byte[] publickey = null; |
206 public xsalsa20poly1305 Clone() { | 208 public xsalsa20poly1305 Clone() { |
207 return new xsalsa20poly1305(sharedkey, nonce); | 209 return new xsalsa20poly1305(sharedkey, nonce); |
208 } | 210 } |
209 } | 211 } |
210 public class edwards25519sha512batch { | 212 public class edwards25519sha512batch { |
211 public Byte[] Sign(Byte[] message, Byte[] secretkey) { | 213 public static Byte[] Sign(Byte[] message, Byte[] secretkey) { |
212 return edwards25519sha512batchimpl.crypto_sign(message, secretkey); | 214 return edwards25519sha512batchimpl.crypto_sign(message, secretkey); |
213 } | 215 } |
214 public int GetSignedSize(int size) { | 216 public static int GetSignedSize(int size) { |
215 return size + 64; | 217 return size + 64; |
216 } | 218 } |
217 public Byte[] Open(Byte[] signed, Byte[] publickey) { | 219 public static Byte[] Open(Byte[] signed, Byte[] publickey) { |
218 return edwards25519sha512batchimpl.crypto_sign_open(signed, publickey); | 220 return edwards25519sha512batchimpl.crypto_sign_open(signed, publickey); |
219 } | 221 } |
220 public unsafe Boolean Verify(Byte[] signed, Byte[] publickey) { | 222 public static unsafe Boolean Verify(Byte[] signed, Byte[] publickey) { |
221 if (publickey.Length != edwards25519sha512batchimpl.PUBLICKEYBYTES) throw new ArgumentException("publickey.Length != PUBLICKEYBYTES"); | 223 if (publickey.Length != edwards25519sha512batchimpl.PUBLICKEYBYTES) throw new ArgumentException("publickey.Length != PUBLICKEYBYTES"); |
222 UInt64 mlen; | 224 UInt64 mlen; |
223 fixed (Byte* smp = signed, pkp = publickey) return edwards25519sha512batchimpl.crypto_sign_open(null, out mlen, smp, (ulong)signed.Length, pkp) == 0; | 225 fixed (Byte* smp = signed, pkp = publickey) return edwards25519sha512batchimpl.crypto_sign_open(null, out mlen, smp, (ulong)signed.Length, pkp) == 0; |
224 } | 226 } |
225 public Byte[] Extract(Byte[] signed) { | 227 public static Byte[] Extract(Byte[] signed) { |
226 if (signed.Length < 64) return null; | 228 if (signed.Length < 64) return null; |
227 Byte[] ret = new Byte[signed.Length - 64]; | 229 Byte[] ret = new Byte[signed.Length - 64]; |
228 Buffer.BlockCopy(signed, 32, ret, 0, ret.Length); | 230 Buffer.BlockCopy(signed, 32, ret, 0, ret.Length); |
229 return ret; | 231 return ret; |
230 } | 232 } |
231 public int GetExtractedSize(int size) { | 233 public static int GetExtractedSize(int size) { |
232 if (size < 64) return -1; | 234 if (size < 64) return -1; |
233 return size - 64; | 235 return size - 64; |
234 } | 236 } |
235 } | 237 } |
238 public class sha512 { | |
239 sha512impl.sha512state state = new sha512impl.sha512state(); | |
240 public sha512() { | |
241 state.init(); | |
242 } | |
243 public unsafe void Process(Byte[] buffer, int offset, int count) { | |
244 if (offset < 0 || count < 0 || offset + count > buffer.Length) throw new ArgumentException("buffer"); | |
245 fixed (Byte* p = buffer) state.process(p + offset, count); | |
246 } | |
247 public unsafe void GetHash(Byte[] hash, int offset) { | |
248 if (offset < 0 || offset + 64 > hash.Length) throw new ArgumentException("hash"); | |
249 fixed (Byte* p = hash) state.finish(p + offset); | |
250 } | |
251 public unsafe Byte[] GetHash() { | |
252 Byte[] hash = new Byte[64]; | |
253 GetHash(hash, 0); | |
254 return hash; | |
255 } | |
256 public static unsafe void GetHash(Byte[] buffer, int offset, int count, Byte[] hash, int hashoffset) { | |
257 if (offset < 0 || offset + count > buffer.Length) throw new ArgumentException("buffer"); | |
258 if (offset < 0 || offset + 64 > hash.Length) throw new ArgumentException("hash"); | |
259 sha512impl.sha512state state = new sha512impl.sha512state(); | |
260 state.init(); | |
261 fixed (Byte* p = buffer) state.process(p + offset, count); | |
262 fixed (Byte* p = hash) state.finish(p + offset); | |
263 } | |
264 public static unsafe Byte[] GetHash(Byte[] buffer, int offset, int count) { | |
265 Byte[] hash = new Byte[64]; | |
266 GetHash(buffer,offset,count,hash,0); | |
267 return hash; | |
268 } | |
269 } | |
270 public class ed25519keypair { | |
271 internal Byte[] key; | |
272 | |
273 public ed25519keypair() { | |
274 Byte[] pk; | |
275 ed25519impl.crypto_sign_keypair(out pk, out key); | |
276 } | |
277 public ed25519keypair(Byte[] key) { | |
278 if (key.Length == 64) { | |
279 this.key = ArrayUtil.ToArray(key); | |
280 }else { | |
281 Byte[] pk; | |
282 ed25519impl.crypto_sign_seed_keypair(out pk, out this.key, key); | |
283 } | |
284 } | |
285 public ed25519keypair(String key) : this(curve25519keypair.DecodeHexString(key, key.Length)) { } | |
286 public Byte[] PublicKey { get { return ArrayUtil.Slice(key, 32, 32); } } | |
287 public Byte[] SecretKey { get { return ArrayUtil.Slice(key, 0, 32); } } | |
288 public Byte[] ExpandedKey { get { return ArrayUtil.ToArray(key); } } | |
289 | |
290 public Byte[] GetSignature(Byte[] message) { | |
291 return ed25519.GetSignature(message, key); | |
292 } | |
293 public Byte[] GetSignature(Byte[] message, int offset, int count) { | |
294 return ed25519.GetSignature(new ArraySegment<Byte>(message, offset, count), key); | |
295 } | |
296 public Byte[] SignMessage(Byte[] message) { | |
297 return ed25519.SignMessage(message, key); | |
298 } | |
299 } | |
300 public class ed25519 { | |
301 public static unsafe Byte[] GetSignature(Byte[] message, Byte[] key) { | |
302 if (message == null) throw new ArgumentNullException("message"); | |
303 if (key.Length != 64) throw new ArgumentException("key"); | |
304 Byte[] sig = new Byte[64]; | |
305 fixed (Byte* sigp = sig, msgp = message, kp = key) ed25519impl.crypto_getsignature(sigp, msgp, message.Length, kp); | |
306 return sig; | |
307 } | |
308 public static unsafe Byte[] GetSignature(ArraySegment<Byte> message, Byte[] key) { | |
309 if (message == null) throw new ArgumentNullException("message"); | |
310 if (key.Length != 64) throw new ArgumentException("key"); | |
311 if (message.Offset < 0 || message.Count < 0 || message.Offset + message.Count > message.Array.Length) throw new ArgumentException("message"); | |
312 Byte[] sig = new Byte[64]; | |
313 fixed (Byte* sigp = sig, msgp = message.Array, kp = key) ed25519impl.crypto_getsignature(sigp, msgp + message.Offset, message.Count, kp); | |
314 return sig; | |
315 } | |
316 public static unsafe Byte[] SignMessage(Byte[] message, Byte[] key) { | |
317 if (key.Length != 64) throw new ArgumentException("key"); | |
318 Byte[] ret = new Byte[message.Length + 64]; | |
319 int smlen; | |
320 fixed (Byte* sm = ret, msgp = message, kp = key) ed25519impl.crypto_sign(sm, out smlen, msgp, message.Length, kp); | |
321 return ret; | |
322 } | |
323 public static unsafe Boolean VerifySignature(Byte[] message, Byte[] signature, Byte[] pk) { | |
324 if (signature.Length < 64) throw new ArgumentException("signature"); | |
325 if (pk.Length < 32) throw new ArgumentException("pk"); | |
326 fixed (Byte* sp = signature, mp = message, kp = pk) return ed25519impl.crypto_sign_verify(sp, mp, message.Length, kp); | |
327 } | |
328 public static unsafe Boolean VerifySignature(ArraySegment<Byte> message, ArraySegment<Byte> signature, Byte[] pk) { | |
329 if (signature.Offset < 0 || signature.Count < 64 || signature.Offset + signature.Count < signature.Array.Length) throw new ArgumentException("signature"); | |
330 if (message.Offset < 0 || message.Count < 0 || message.Offset + message.Count < message.Array.Length) throw new ArgumentException("message"); | |
331 if (pk.Length < 32) throw new ArgumentException("pk"); | |
332 fixed (Byte* sp = signature.Array, mp = message.Array, kp = pk) return ed25519impl.crypto_sign_verify(sp + signature.Offset, mp + message.Offset, message.Count, kp); | |
333 } | |
334 public static unsafe Boolean VerifySignedMessage(Byte[] signedmessage, Byte[] pk) { | |
335 if (signedmessage.Length < 64) throw new ArgumentException("signedmessage"); | |
336 if (pk.Length < 32) throw new ArgumentException("pk"); | |
337 fixed (Byte* mp = signedmessage, kp = pk) return ed25519impl.crypto_sign_verify(mp, mp + 64, signedmessage.Length - 64, kp); | |
338 } | |
339 public static Byte[] ExtractSignedMessage(Byte[] signedmessage) { | |
340 return ArrayUtil.Slice(signedmessage, 64); | |
341 } | |
342 public static Byte[] ExtractSignedMessage(ArraySegment<Byte> signedmessage) { | |
343 return ArrayUtil.Slice(signedmessage.Array, signedmessage.Offset + 64, signedmessage.Count - 64); | |
344 } | |
345 public static ArraySegment<Byte> ExtractSignedMessageFast(Byte[] signedmessage) { | |
346 return new ArraySegment<Byte>(signedmessage, 64, signedmessage.Length - 64); | |
347 } | |
348 public static ArraySegment<Byte> ExtractSignedMessageFast(ArraySegment<Byte> signedmessage) { | |
349 return new ArraySegment<Byte>(signedmessage.Array, signedmessage.Offset + 64, signedmessage.Count - 64); | |
350 } | |
351 public static Byte[] OpenSignedMessage(Byte[] signedmessage, Byte[] pk) { | |
352 if (!VerifySignedMessage(signedmessage, pk)) return null; | |
353 return ExtractSignedMessage(signedmessage); | |
354 } | |
355 } | |
236 } | 356 } |