From 8dec3688781b2e15ffaad05ce23aba7d0c378230 Mon Sep 17 00:00:00 2001 From: Giovanni Petrantoni Date: Fri, 14 Feb 2020 11:56:05 +0900 Subject: [PATCH] Add Curve25519 (BearSSL) required operations for noise --- libp2p/crypto/chacha20poly1305.nim | 2 +- libp2p/crypto/curve25519.nim | 82 ++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 libp2p/crypto/curve25519.nim diff --git a/libp2p/crypto/chacha20poly1305.nim b/libp2p/crypto/chacha20poly1305.nim index fc09a2b..bdc9a84 100644 --- a/libp2p/crypto/chacha20poly1305.nim +++ b/libp2p/crypto/chacha20poly1305.nim @@ -23,7 +23,7 @@ const ChaChaPolyTagSize = 16 type - ChaChaPoly = object + ChaChaPoly* = object ChaChaPolyKey* = array[ChaChaPolyKeySize, byte] ChaChaPolyNonce* = array[ChaChaPolyNonceSize, byte] ChaChaPolyTag* = array[ChaChaPolyTagSize, byte] diff --git a/libp2p/crypto/curve25519.nim b/libp2p/crypto/curve25519.nim new file mode 100644 index 0000000..a9a18c2 --- /dev/null +++ b/libp2p/crypto/curve25519.nim @@ -0,0 +1,82 @@ +## Nim-Libp2p +## Copyright (c) 2020 Status Research & Development GmbH +## Licensed under either of +## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) +## * MIT license ([LICENSE-MIT](LICENSE-MIT)) +## at your option. +## This file may not be copied, modified, or distributed except according to +## those terms. + +## This module integrates BearSSL ChaCha20+Poly1305 +## +## This module uses unmodified parts of code from +## BearSSL library +## Copyright(C) 2018 Thomas Pornin . + +# RFC @ https://tools.ietf.org/html/rfc7748 + +import bearssl + +const + Curve25519KeySize = 32 + +type + Curve25519* = object + Curve25519Key* = array[Curve25519KeySize, byte] + pcuchar = ptr cuchar + + +const + ForbiddenCurveValues: array[12, Curve25519Key] = [ + [0.byte, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [1.byte, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [224.byte, 235, 122, 124, 59, 65, 184, 174, 22, 86, 227, 250, 241, 159, 196, 106, 218, 9, 141, 235, 156, 50, 177, 253, 134, 98, 5, 22, 95, 73, 184, 0], + [95.byte, 156, 149, 188, 163, 80, 140, 36, 177, 208, 177, 85, 156, 131, 239, 91, 4, 68, 92, 196, 88, 28, 142, 134, 216, 34, 78, 221, 208, 159, 17, 87], + [236.byte, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127], + [237.byte, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127], + [238.byte, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127], + [205.byte, 235, 122, 124, 59, 65, 184, 174, 22, 86, 227, 250, 241, 159, 196, 106, 218, 9, 141, 235, 156, 50, 177, 253, 134, 98, 5, 22, 95, 73, 184, 128], + [76.byte, 156, 149, 188, 163, 80, 140, 36, 177, 208, 177, 85, 156, 131, 239, 91, 4, 68, 92, 196, 88, 28, 142, 134, 216, 34, 78, 221, 208, 159, 17, 215], + [217.byte, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], + [218.byte, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], + [219.byte, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25], + ] + +let defaultBrEc = brEcGetDefault() + +proc mul*(_: type[Curve25519], dst: var Curve25519Key, scalar: Curve25519Key, point: Curve25519Key) = + # The source point is provided in array G (of size Glen bytes); + # the multiplication result is written over it. + dst = scalar + let + res = defaultBrEc.mul( + cast[pcuchar](addr dst[0]), + Curve25519KeySize, + cast[pcuchar](unsafeAddr point[0]), + Curve25519KeySize, + EC_curve25519.cint) + assert res == 1 + +proc mulgen*(_: type[Curve25519], dst: var Curve25519Key, scalar: Curve25519Key) = + while true: + let + size = defaultBrEc.mulgen( + cast[pcuchar](addr dst[0]), + cast[pcuchar](unsafeAddr scalar[0]), + Curve25519KeySize, + EC_curve25519.cint) + assert size == Curve25519KeySize + for forbid in ForbiddenCurveValues: + if dst == forbid: + continue + break + +when isMainModule: + var + key: Curve25519Key + dst: Curve25519Key + dst2: Curve25519Key + Curve25519.mulgen(dst, key) + echo dst + Curve25519.mul(dst2, dst, key) + echo dst2