Skip to content

Commit

Permalink
use constant-time increment and isZero
Browse files Browse the repository at this point in the history
  • Loading branch information
ahdinosaur committed Nov 27, 2023
1 parent 79508f8 commit 21a7bc5
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 24 deletions.
24 changes: 19 additions & 5 deletions js/secret-channel/src/crypto-javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@ const { chacha20poly1305 } = require('@noble/ciphers/chacha')

const debug = require('./debug')

const IS_NODE =
typeof process !== 'undefined' &&
typeof process.versions !== 'undefined' &&
typeof process.versions.node !== 'undefined'

module.exports = {
encrypt,
decrypt,
increment,
isZero,
}

function encrypt(keyArg, nonceArg, plaintextArg) {
Expand All @@ -27,3 +24,20 @@ function encrypt(keyArg, nonceArg, plaintextArg) {
function decrypt(key, nonce, ciphertext) {
return chacha20poly1305(key, nonce).encrypt(ciphertext)
}

function increment(buf) {
const len = buf.length
let c = 1
for (let i = 0; i < len; i++) {
c += buf[i]
buf[i] = c
c >>= 8
}
}

function isZero(buf) {
const len = buf.length
let d = 0
for (let i = 0; i < len; i++) d |= buf[i]
return d === 0
}
12 changes: 12 additions & 0 deletions js/secret-channel/src/crypto-native.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ const {
crypto_aead_chacha20poly1305_ietf_encrypt: sodiumEncrypt,
crypto_aead_chacha20poly1305_ietf_decrypt: sodiumDecrypt,
crypto_aead_chacha20poly1305_ietf_ABYTES: ABYTES,
sodium_increment: sodiumIncrement,
sodium_is_zero: sodiumIsZero,
} = require('sodium-native')

const debug = require('./debug')

module.exports = {
encrypt,
decrypt,
increment,
isZero,
}

function encrypt(key, nonce, plaintext) {
Expand All @@ -25,3 +29,11 @@ function decrypt(key, nonce, ciphertext) {
sodiumDecrypt(plaintext, null, ciphertext, null, nonce, key)
return plaintext
}

function increment(buffer) {
sodiumIncrement(buffer)
}

function isZero(buffer) {
return sodiumIsZero(buffer)
}
15 changes: 7 additions & 8 deletions js/secret-channel/src/protocol.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
const b4a = require('b4a')

const { incrementBuffer } = require('./util')
const { KEY_SIZE, LENGTH_OR_END_PLAINTEXT, LENGTH_OR_END_CIPHERTEXT } = require('./constants')

const NONCE_SIZE = 12

class StreamCounter {
#increment
#nonce

constructor() {
constructor(increment) {
this.#increment = increment
this.#nonce = b4a.alloc(NONCE_SIZE, 0)
}

next() {
incrementBuffer(this.#nonce)
this.#increment(this.#nonce)
return this.#nonce
}
}
Expand All @@ -31,7 +32,7 @@ class StreamEncrypter {
}
this.#key = key

this.#counter = new StreamCounter()
this.#counter = new StreamCounter(crypto.increment)
}

next(plaintext) {
Expand Down Expand Up @@ -69,8 +70,6 @@ class StreamEncrypter {
}
}

const endOfStreamBytes = b4a.alloc(LENGTH_OR_END_PLAINTEXT, 0)

class StreamDecrypter {
#crypto
#key
Expand All @@ -84,7 +83,7 @@ class StreamDecrypter {
}
this.#key = key

this.#counter = new StreamCounter()
this.#counter = new StreamCounter(crypto.increment)
}

lengthOrEnd(ciphertext) {
Expand All @@ -96,7 +95,7 @@ class StreamDecrypter {

const plaintext = this.#decrypt(ciphertext)

if (plaintext.equals(endOfStreamBytes)) {
if (this.#crypto.isZero(plaintext)) {
// TODO delete the key
return {
type: 'end-of-stream',
Expand Down
11 changes: 0 additions & 11 deletions js/secret-channel/src/util.js

This file was deleted.

0 comments on commit 21a7bc5

Please sign in to comment.