Add tests + requirements

This commit is contained in:
Jazz Turner-Baggs 2025-10-08 17:52:43 -07:00
parent 520ce1cb80
commit 285b6f2d2e
6 changed files with 173 additions and 1 deletions

10
.gitmodules vendored
View File

@ -31,3 +31,13 @@
url = https://github.com/johnnovak/illwill.git
ignore = untracked
branch = master
[submodule "vendor/nim_chacha20_poly1305"]
path = vendor/nim_chacha20_poly1305
url = https://github.com/lantos-lgtm/nim_chacha20_poly1305.git
ignore = untracked
branch = master
[submodule "vendor/constantine"]
path = vendor/constantine
url = https://github.com/mratsim/constantine.git
ignore = untracked
branch = master

View File

@ -1,6 +1,7 @@
import naxolotl/[
naxolotl,
curve25519
curve25519,
types
]
export naxolotl, curve25519

View File

@ -0,0 +1 @@
switch("path", "$projectDir/src")

158
tests/test_naxolotl.nim Normal file
View File

@ -0,0 +1,158 @@
import unittest
import naxolotl
import results
import random
import sequtils
import strutils
import naxolotl/utils
# Key share test from RFC-7748:
const ks7748_a_priv = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"
const ks7748_a_pub = "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a" # Public key point (x co-ord)
const ks7748_b_priv = "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb"
const ks7748_b_pub = "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f" # Public key point (x co-ord)s
const ks7748_shared_key = "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
# import parseutils
proc hexToArray*[N: static[int]](hexStr: string): array[N, byte] =
## Converts hex string to fixed-size byte array
if hexStr.len != N * 2:
raise newException(ValueError,
"Hex string length (" & $hexStr.len & ") doesn't match array size (" & $(
N*2) & ")")
var result: array[N, byte]
for i in 0..<N:
result[i] = byte(parseHexInt(hexStr[2*i .. 2*i+1]))
func loadTestKeys() : (array[32,byte],array[32,byte],array[32,byte],array[32,byte]) =
let a_priv = hexToArray[32](ks7748_a_priv)
let a_pub = hexToArray[32](ks7748_a_pub)
let b_priv = hexToArray[32](ks7748_b_priv)
let b_pub = hexToArray[32](ks7748_b_pub)
(a_priv, a_pub, b_priv, b_pub)
func createTestInstances(a: array[32, byte], apub: array[32, byte], b: array[32, byte], bpub: array[32, byte],sk: array[32, byte]) : (Doubleratchet, Doubleratchet) =
let adr = initDoubleratchet(sk, a, bpub, true)
let bdr = initDoubleratchet(sk, b, apub, false)
(adr,bdr)
suite "Doubleratchet":
test "roundtrip":
let (a_priv, a_pub, b_priv, b_pub) = loadTestKeys()
let sk = hexToArray[32](ks7748_shared_key)
var adr = initDoubleratchet(sk, a_priv, b_pub, true)
var bdr = initDoubleratchet(sk, b_priv, a_pub, true)
var msg :seq[byte] = @[1,2,3,4,5,6,7,8,9,10]
let (header, ciphertext) = adr.encrypt(msg)
let r = bdr.decrypt(header, ciphertext, @[])
assert r.isOk()
assert r.get() == msg
test "sequence":
let (a_priv, a_pub, b_priv, b_pub) = loadTestKeys()
let sk = hexToArray[32](ks7748_shared_key)
var adr = initDoubleratchet(sk, a_priv, b_pub, true)
var bdr = initDoubleratchet(sk, b_priv, a_pub, true)
var msg0 :seq[byte] = @[1,2,3,4,5,6,7,8,9,10]
var msg1 :seq[byte] = @[6,7,8,9,10,1,2,3,4,5]
let (header0, ciphertext0) = adr.encrypt(msg0)
let (header1, ciphertext1) = adr.encrypt(msg1)
let r = bdr.decrypt(header1, ciphertext1, @[])
assert r.isOk()
let recv_msg = r.get()
assert recv_msg == msg1
test "out of order":
let (a_priv, a_pub, b_priv, b_pub) = loadTestKeys()
let sk = hexToArray[32](ks7748_shared_key)
var adr = initDoubleratchet(sk, a_priv, b_pub, true)
var bdr = initDoubleratchet(sk, b_priv, a_pub, true)
var msg : seq[ seq[byte]]= @[
@[1,2,3,4,5,6,7,8,9,10],
@[43,32,1,2],
@[212,122,0,21,23,4,5,71,29,84,167,31,0,1,92,211,5,53,65],
@[122,0,21,23,4,5,71,29,84,167,31,0,1,92,211,5,53,65,212],
@[14,35,17,22,14,63,34,0,1,217,218,29,51,69,33],
]
var ciphertexts : seq[(DrHeader, seq[byte])] = @[]
for m in mitems(msg):
ciphertexts.add(adr.encrypt(m))
randomize(1233) # make reproducible
var indicies = toSeq(0..msg.high)
shuffle(indicies)
for i in indicies:
var m = msg[i]
var (header, ciphertext) = ciphertexts[i]
let r = bdr.decrypt(header, ciphertext, @[])
assert r.isOk()
assert r.get() == m
test "tag mismatch":
let (a_priv, a_pub, b_priv, b_pub) = loadTestKeys()
let sk = hexToArray[32](ks7748_shared_key)
var adr = initDoubleratchet(sk, a_priv, b_pub, true)
var bdr = initDoubleratchet(sk, b_priv, a_pub, true)
var msg :seq[byte] = @[1,2,3,4,5,6,7,8,9,10]
var (header, ciphertext) = adr.encrypt(msg)
# Modify the tag
ciphertext[^4] = ciphertext[^4] xor 1
let r = bdr.decrypt(header, ciphertext, @[])
assert r.isErr()
test "decryption failure":
let (a_priv, a_pub, b_priv, b_pub) = loadTestKeys()
let sk = hexToArray[32](ks7748_shared_key)
var adr = initDoubleratchet(sk, a_priv, b_pub, true)
var bdr = initDoubleratchet(sk, b_priv, a_pub, true)
var msg :seq[byte] = @[1,2,3,4,5,6,7,8,9,10]
var (header, ciphertext) = adr.encrypt(msg)
ciphertext[15] = ciphertext[15] xor 1
let r = bdr.decrypt(header, ciphertext, @[])
assert r.isErr()

1
vendor/constantine vendored Submodule

@ -0,0 +1 @@
Subproject commit d6aae1eca3775d6317e11b169edef0249162ce22

1
vendor/nim_chacha20_poly1305 vendored Submodule

@ -0,0 +1 @@
Subproject commit ad06aff319bdb5d61cebd56d2d0e31c3516112c6