This repository has been archived by the owner on Jul 30, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: init * feat: add functions * feat: add complete implementation
- Loading branch information
Tomio
committed
Apr 2, 2022
1 parent
e362b74
commit c24d717
Showing
10 changed files
with
237 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { GenericHash } from '../bindings'; | ||
import type { Nullish } from '../types'; | ||
|
||
const generichash = new GenericHash(); | ||
|
||
export interface GenericHashState { | ||
opaque: Uint8Array; | ||
} | ||
|
||
export const crypto_generichash_BYTES = generichash.cryptoGenerichashBytes; | ||
export const crypto_generichash_BYTES_MAX = generichash.cryptoGenerichashBytesMax; | ||
export const crypto_generichash_BYTES_MIN = generichash.cryptoGenerichashBytesMin; | ||
export const crypto_generichash_KEYBYTES = generichash.cryptoGenerichashKeybytes; | ||
export const crypto_generichash_KEYBYTES_MAX = generichash.cryptoGenerichashKeybytesMax; | ||
export const crypto_generichash_KEYBYTES_MIN = generichash.cryptoGenerichashKeybytesMin; | ||
|
||
/** @see https://docs.rs/sodiumoxide/latest/sodiumoxide/crypto/generichash/fn.hash.html */ | ||
export const crypto_generichash = (data: Uint8Array, out_len: Nullish<number>, key: Nullish<Uint8Array>): Uint8Array => | ||
generichash.crypto_generichash(data, out_len, key); | ||
|
||
/** @see https://docs.rs/libsodium-sys/latest/libsodium_sys/fn.crypto_generichash_final.html */ | ||
export const crypto_generichash_final = (state: GenericHashState, out_len: number): Uint8Array => | ||
generichash.crypto_generichash_final(state, out_len); | ||
|
||
/** @see https://docs.rs/sodiumoxide/latest/sodiumoxide/crypto/generichash/struct.State.html#method.new */ | ||
export const crypto_generichash_init = (out_len: Nullish<number>, key: Nullish<Uint8Array>): GenericHashState => | ||
generichash.crypto_generichash_init(out_len, key); | ||
|
||
/** @see https://docs.rs/libsodium-sys/latest/libsodium_sys/fn.crypto_generichash_keygen.html */ | ||
export const crypto_generichash_keygen = (): Uint8Array => generichash.crypto_generichash_keygen(); | ||
|
||
/** @see https://docs.rs/libsodium-sys/latest/libsodium_sys/fn.crypto_generichash_update.html */ | ||
export const crypto_generichash_update = (state: GenericHashState, data: Uint8Array): GenericHashState => | ||
generichash.crypto_generichash_update(state, data); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
use crate::vec_arr_func; | ||
use dryoc::constants::*; | ||
use libc::c_ulonglong; | ||
use napi::bindgen_prelude::*; | ||
use sodiumoxide::{crypto::generichash, ffi, init}; | ||
|
||
vec_arr_func!(to_opaque, u8, 384); | ||
|
||
#[napi(object)] | ||
pub struct GenericHashState { | ||
pub opaque: Uint8Array, | ||
} | ||
|
||
#[napi] | ||
pub struct GenericHash {} | ||
|
||
#[napi] | ||
impl GenericHash { | ||
#[napi(constructor)] | ||
pub fn new() -> Self { | ||
init().unwrap(); | ||
GenericHash {} | ||
} | ||
|
||
#[napi(js_name = "crypto_generichash")] | ||
pub fn crypto_generichash( | ||
&self, | ||
data: Uint8Array, | ||
out_len: Option<u32>, | ||
key: Option<Uint8Array>, | ||
) -> Uint8Array { | ||
let ol = match out_len { | ||
Some(l) => Some(l as usize), | ||
None => None, | ||
}; | ||
|
||
let k = match key { | ||
Some(ky) => Some(ky.to_vec()), | ||
None => None, | ||
}; | ||
|
||
let d = generichash::hash(&data, ol, k).unwrap(); | ||
|
||
Uint8Array::new(d.as_ref().to_vec()) | ||
} | ||
|
||
#[napi(js_name = "crypto_generichash_final")] | ||
pub fn crypto_generichash_final(&self, state: GenericHashState, out_len: u32) -> Result<Uint8Array> { | ||
let mut result = generichash::Digest::new(out_len as usize); | ||
let mut st = ffi::crypto_generichash_state { | ||
opaque: to_opaque(&state.opaque), | ||
}; | ||
let rc = | ||
unsafe { ffi::crypto_generichash_final(&mut st, result.data.as_mut_ptr(), result.len) }; | ||
|
||
match rc { | ||
0 => Ok(Uint8Array::new(result.data.to_vec())), | ||
_ => Err(Error::new( | ||
Status::GenericFailure, | ||
"Failed to execute".to_string(), | ||
)), | ||
} | ||
} | ||
|
||
#[napi(js_name = "crypto_generichash_init")] | ||
pub fn crypto_generichash_init( | ||
&self, | ||
out_len: Option<u32>, | ||
key: Option<Uint8Array>, | ||
) -> GenericHashState { | ||
let ol = match out_len { | ||
Some(l) => Some(l as usize), | ||
None => None, | ||
}; | ||
|
||
let k = match key { | ||
Some(ky) => Some(ky.to_vec()), | ||
None => None, | ||
}; | ||
|
||
let s = generichash::State::new(ol, k).unwrap(); | ||
|
||
GenericHashState { | ||
opaque: Uint8Array::new(s.state.opaque.to_vec()), | ||
} | ||
} | ||
|
||
#[napi(js_name = "crypto_generichash_keygen")] | ||
pub fn crypto_generichash_keygen(&self) -> Uint8Array { | ||
let mut k = [0u8; CRYPTO_GENERICHASH_KEYBYTES]; | ||
|
||
unsafe { | ||
ffi::crypto_generichash_keygen(k.as_mut_ptr()); | ||
}; | ||
|
||
Uint8Array::new(k.to_vec()) | ||
} | ||
|
||
#[napi(js_name = "crypto_generichash_update")] | ||
pub fn crypto_generichash_update( | ||
&self, | ||
state: GenericHashState, | ||
data: Uint8Array, | ||
) -> Result<GenericHashState> { | ||
let mut st = ffi::crypto_generichash_state { | ||
opaque: to_opaque(&state.opaque), | ||
}; | ||
|
||
let rc = unsafe { | ||
ffi::crypto_generichash_update(&mut st, data.as_ptr(), data.len() as c_ulonglong) | ||
}; | ||
|
||
match rc { | ||
0 => Ok(GenericHashState { | ||
opaque: Uint8Array::new(st.opaque.to_vec()), | ||
}), | ||
_ => Err(Error::new( | ||
Status::GenericFailure, | ||
"Failed to execute".to_string(), | ||
)), | ||
} | ||
} | ||
|
||
#[napi(getter)] | ||
pub fn crypto_generichash_bytes(&self) -> u32 { | ||
CRYPTO_GENERICHASH_BYTES as u32 | ||
} | ||
|
||
#[napi(getter)] | ||
pub fn crypto_generichash_bytes_max(&self) -> u32 { | ||
CRYPTO_GENERICHASH_BYTES_MAX as u32 | ||
} | ||
|
||
#[napi(getter)] | ||
pub fn crypto_generichash_bytes_min(&self) -> u32 { | ||
CRYPTO_GENERICHASH_BYTES_MIN as u32 | ||
} | ||
|
||
#[napi(getter)] | ||
pub fn crypto_generichash_keybytes(&self) -> u32 { | ||
CRYPTO_GENERICHASH_KEYBYTES as u32 | ||
} | ||
|
||
#[napi(getter)] | ||
pub fn crypto_generichash_keybytes_max(&self) -> u32 { | ||
CRYPTO_GENERICHASH_KEYBYTES_MAX as u32 | ||
} | ||
|
||
#[napi(getter)] | ||
pub fn crypto_generichash_keybytes_min(&self) -> u32 { | ||
CRYPTO_GENERICHASH_KEYBYTES_MIN as u32 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import * as sodium from '../dist'; | ||
|
||
test('generichash', () => { | ||
const message = 'Science, math, technology, engineering, and compassion for others.'; | ||
const piece1 = message.slice(0, 16); | ||
const piece2 = message.slice(16); | ||
|
||
let hash1 = Buffer.from(sodium.crypto_generichash(Buffer.from(message), 32, null)); | ||
expect(hash1.toString('hex')).toBe('47c1fdbde32b30b9c54dd47cf88ba92d2d05df1265e342c9563ed56aee84ab02'); | ||
|
||
let state = sodium.crypto_generichash_init(32, null); | ||
let state1 = sodium.crypto_generichash_update(state, Buffer.from(piece1)); | ||
let state2 = sodium.crypto_generichash_update(state1, Buffer.from(piece2)); | ||
let hash2 = Buffer.from(sodium.crypto_generichash_final(state2, 32)); | ||
expect(hash2.toString('hex', 0, 32)).toBe(hash1.toString('hex', 0, 32)); | ||
|
||
const key = Buffer.from(sodium.crypto_generichash_keygen()); | ||
hash1 = Buffer.from(sodium.crypto_generichash(Buffer.from(message), 32, key)); | ||
state = sodium.crypto_generichash_init(32, key); | ||
state1 = sodium.crypto_generichash_update(state, Buffer.from(piece1)); | ||
state2 = sodium.crypto_generichash_update(state1, Buffer.from(piece2)); | ||
hash2 = Buffer.from(sodium.crypto_generichash_final(state2, 32)); | ||
|
||
expect(hash1.toString('hex', 0, 32)).toBe(hash2.toString('hex', 0, 32)); | ||
}); |