Skip to content

Commit

Permalink
Fixups to keep in sync with draft-10
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinlewi committed Oct 10, 2024
1 parent df29524 commit 177b284
Show file tree
Hide file tree
Showing 9 changed files with 467 additions and 1,500 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ name = "opaque-ke"
readme = "README.md"
repository = "https://github.com/facebook/opaque-ke"
rust-version = "1.74"
version = "3.0.0-pre.5"
version = "2.1.0-pre.1"

[features]
argon2 = ["dep:argon2"]
Expand Down Expand Up @@ -39,7 +39,7 @@ serde = { version = "1", default-features = false, features = [
"derive",
], optional = true }
subtle = { version = "2.3", default-features = false }
voprf = { version = "0.5", default-features = false, features = ["danger"] }
voprf = { version = "0.4.1", default-features = false, features = ["danger"] }
zeroize = { version = "1.5", features = ["zeroize_derive"] }

[target.'cfg(target_arch = "wasm32")'.dependencies]
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Installation
Add the following line to the dependencies of your `Cargo.toml`:

```
opaque-ke = "3.0.0-pre.5"
opaque-ke = "2.1.0-pre.1"
```

### Minimum Supported Rust Version
Expand All @@ -40,7 +40,7 @@ Resources
---------

- [OPAQUE academic publication](https://eprint.iacr.org/2018/163.pdf), including formal definitions and a proof of security
- [draft-irtf-cfrg-opaque-16](https://datatracker.ietf.org/doc/draft-irtf-cfrg-opaque/16/), containing a detailed (byte-level) specification for OPAQUE
- [draft-irtf-cfrg-opaque-10](https://datatracker.ietf.org/doc/draft-irtf-cfrg-opaque/10/), containing a detailed (byte-level) specification for OPAQUE
- ["Let's talk about PAKE"](https://blog.cryptographyengineering.com/2018/10/19/lets-talk-about-pake/), an introductory blog post written by Matthew Green that covers OPAQUE
- [@serenity-kit/opaque](https://github.com/serenity-kit/opaque), a WebAssembly package for this library
- [opaque-wasm](https://github.com/marucjmar/opaque-wasm), a WebAssembly package for this library. A comparison between `@serenity-kit/opaque` and `opaque-wasm` can be found [here](https://opaque-documentation.netlify.app/docs/faq#how-does-it-compare-to-opaque-wasm)
Expand Down
4 changes: 2 additions & 2 deletions src/key_exchange/group/elliptic_curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ where

// Implements the `HashToScalar()` function from
// <https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-19.html#section-4>
fn hash_to_scalar<H>(input: &[&[u8]], dst: &[&[u8]]) -> Result<Self::Sk, InternalError>
fn hash_to_scalar<'a, H>(input: &[&[u8]], dst: &[u8]) -> Result<Self::Sk, InternalError>
where
H: BlockSizeUser + Default + FixedOutput + HashMarker,
H::OutputSize: IsLess<U256> + IsLessOrEqual<H::BlockSize>,
{
Self::hash_to_scalar::<ExpandMsgXmd<H>>(input, dst)
Self::hash_to_scalar::<ExpandMsgXmd<H>>(input, &[dst])
.map_err(|_| InternalError::HashToScalar)
.and_then(|scalar| {
if bool::from(scalar.is_zero()) {
Expand Down
37 changes: 28 additions & 9 deletions src/key_exchange/group/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub mod ristretto255;
use digest::core_api::BlockSizeUser;
use digest::{FixedOutput, HashMarker, OutputSizeUser};
use generic_array::sequence::Concat;
use generic_array::typenum::{IsLess, IsLessOrEqual, U256};
use generic_array::typenum::{IsLess, IsLessOrEqual, U11, U256};
use generic_array::{ArrayLength, GenericArray};
use rand::{CryptoRng, RngCore};
use zeroize::Zeroize;
Expand Down Expand Up @@ -49,7 +49,7 @@ pub trait KeGroup {
/// # Errors
/// [`InternalError::HashToScalar`] if the `input` is empty or longer then
/// [`u16::MAX`].
fn hash_to_scalar<H>(input: &[&[u8]], dst: &[&[u8]]) -> Result<Self::Sk, InternalError>
fn hash_to_scalar<H>(input: &[&[u8]], dst: &[u8]) -> Result<Self::Sk, InternalError>
where
H: BlockSizeUser + Default + FixedOutput + HashMarker,
H::OutputSize: IsLess<U256> + IsLessOrEqual<H::BlockSize>;
Expand All @@ -69,11 +69,8 @@ pub trait KeGroup {
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
let dst_1 = GenericArray::from(STR_DERIVE_KEYPAIR)
.concat(STR_OPRF.into())
.concat([voprf::Mode::Oprf.to_u8()].into())
.concat([b'-'].into());
let dst_2 = CS::ID.as_bytes();
let context_string = create_context_string::<CS>(voprf::Mode::Oprf);
let dst = GenericArray::from(STR_DERIVE_KEYPAIR).concat(context_string);

let info_len = i2osp_2(info.len())
.map_err(|_| InternalError::OprfError(voprf::Error::DeriveKeyPair))?;
Expand All @@ -84,7 +81,7 @@ pub trait KeGroup {
// || contextString)
let sk_s = Self::hash_to_scalar::<CS::Hash>(
&[&seed, &info_len, info, &counter.to_be_bytes()],
&[&dst_1, dst_2],
&dst,
)
.map_err(|_| InternalError::OprfError(voprf::Error::DeriveKeyPair))?;

Expand Down Expand Up @@ -115,9 +112,31 @@ pub trait KeGroup {
// Helper functions used to compute DeriveAuthKeyPair() (taken from the voprf
// crate)

const STR_OPRF: [u8; 7] = *b"OPRFV1-";
const STR_VOPRF: [u8; 8] = *b"VOPRF10-";
const STR_DERIVE_KEYPAIR: [u8; 13] = *b"DeriveKeyPair";

/// Generates the contextString parameter as defined in
/// <https://datatracker.ietf.org/doc/draft-irtf-cfrg-voprf/>
fn create_context_string<CS: voprf::CipherSuite>(mode: voprf::Mode) -> GenericArray<u8, U11>
where
<CS::Hash as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<CS::Hash as BlockSizeUser>::BlockSize>,
{
// FIXME: this should be in voprf library
let cs_id_u16: u16 = match CS::ID {
"ristretto255-SHA512" => 0x0001,
"decaf448-SHAKE256" => 0x0002,
"P256-SHA256" => 0x0003,
"P384-SHA384" => 0x0004,
"P521-SHA512" => 0x0005,
_ => panic!("Incompatible ciphersuite: {}", CS::ID),
};

GenericArray::from(STR_VOPRF)
.concat([mode.to_u8()].into())
.concat(cs_id_u16.to_be_bytes().into())
}

fn i2osp_2(input: usize) -> Result<[u8; 2], InternalError> {
u16::try_from(input)
.map(|input| input.to_be_bytes())
Expand Down
4 changes: 2 additions & 2 deletions src/key_exchange/group/ristretto255.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ impl KeGroup for Ristretto255 {

// Implements the `HashToScalar()` function from
// <https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-19.html#section-4>
fn hash_to_scalar<'a, H>(input: &[&[u8]], dst: &[&[u8]]) -> Result<Self::Sk, InternalError>
fn hash_to_scalar<'a, H>(input: &[&[u8]], dst: &[u8]) -> Result<Self::Sk, InternalError>
where
H: BlockSizeUser + Default + FixedOutput + HashMarker,
H::OutputSize: IsLess<U256> + IsLessOrEqual<H::BlockSize>,
{
<voprf::Ristretto255 as Group>::hash_to_scalar::<H>(input, dst)
<voprf::Ristretto255 as Group>::hash_to_scalar::<H>(input, &[dst])
.map_err(InternalError::OprfInternalError)
}

Expand Down
Loading

0 comments on commit 177b284

Please sign in to comment.