Check for small subgroup components when using the EdwardsPoint group for the OPRF
A malicious attacker sending a small point could lead the server / user to leak private information. The check avoiding mixed order points (rather than just small) is prohibitively expensive, and I don't know how an attacker would extract any data from that => we focus on a small order check. Fixes #34.
This commit is contained in:
Generated
+7
@@ -1,5 +1,11 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
@@ -451,6 +457,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
|||||||
name = "opaque-ke"
|
name = "opaque-ke"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
"criterion",
|
"criterion",
|
||||||
"curve25519-dalek",
|
"curve25519-dalek",
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ x25519-dalek = { version = "0.6.0", default-features = false, features = ["std"]
|
|||||||
zeroize = "1.1"
|
zeroize = "1.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
anyhow = "1.0.32"
|
||||||
base64 = "0.12.3"
|
base64 = "0.12.3"
|
||||||
criterion = "0.3.3"
|
criterion = "0.3.3"
|
||||||
hex = "0.4.2"
|
hex = "0.4.2"
|
||||||
|
|||||||
+66
-2
@@ -131,9 +131,14 @@ impl Group for EdwardsPoint {
|
|||||||
fn from_element_slice(
|
fn from_element_slice(
|
||||||
element_bits: &GenericArray<u8, Self::ElemLen>,
|
element_bits: &GenericArray<u8, Self::ElemLen>,
|
||||||
) -> Result<Self, InternalPakeError> {
|
) -> Result<Self, InternalPakeError> {
|
||||||
CompressedEdwardsY::from_slice(element_bits)
|
let point = CompressedEdwardsY::from_slice(element_bits)
|
||||||
.decompress()
|
.decompress()
|
||||||
.ok_or_else(|| InternalPakeError::PointError)
|
.ok_or_else(|| InternalPakeError::PointError)?;
|
||||||
|
|
||||||
|
if point.is_small_order() {
|
||||||
|
return Err(InternalPakeError::SubGroupError);
|
||||||
|
}
|
||||||
|
Ok(point)
|
||||||
}
|
}
|
||||||
// serialization of a group element
|
// serialization of a group element
|
||||||
fn to_arr(&self) -> GenericArray<u8, Self::ElemLen> {
|
fn to_arr(&self) -> GenericArray<u8, Self::ElemLen> {
|
||||||
@@ -164,3 +169,62 @@ impl Group for EdwardsPoint {
|
|||||||
.mul_by_cofactor()
|
.mul_by_cofactor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
|
|
||||||
|
const EIGHT_TORSION: [[u8; 32]; 8] = [
|
||||||
|
[
|
||||||
|
1, 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,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
199, 23, 106, 112, 61, 77, 216, 79, 186, 60, 11, 118, 13, 16, 103, 15, 42, 32, 83, 250,
|
||||||
|
44, 57, 204, 198, 78, 199, 253, 119, 146, 172, 3, 122,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
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, 128,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
38, 232, 149, 143, 194, 178, 39, 176, 69, 195, 244, 137, 242, 239, 152, 240, 213, 223,
|
||||||
|
172, 5, 211, 198, 51, 57, 177, 56, 2, 136, 109, 83, 252, 5,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
236, 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,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
38, 232, 149, 143, 194, 178, 39, 176, 69, 195, 244, 137, 242, 239, 152, 240, 213, 223,
|
||||||
|
172, 5, 211, 198, 51, 57, 177, 56, 2, 136, 109, 83, 252, 133,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
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, 0,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
199, 23, 106, 112, 61, 77, 216, 79, 186, 60, 11, 118, 13, 16, 103, 15, 42, 32, 83, 250,
|
||||||
|
44, 57, 204, 198, 78, 199, 253, 119, 146, 172, 3, 250,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
fn deserialize_point(pt: &[u8]) -> Result<EdwardsPoint> {
|
||||||
|
let mut bytes = [0u8; 32];
|
||||||
|
bytes.copy_from_slice(&pt[..32]);
|
||||||
|
|
||||||
|
curve25519_dalek::edwards::CompressedEdwardsY(bytes)
|
||||||
|
.decompress()
|
||||||
|
.ok_or_else(|| anyhow!("Point decompression failed!"))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_small_subgroup_edwards() {
|
||||||
|
for i in 0..8 {
|
||||||
|
let pt = &EIGHT_TORSION[i][..];
|
||||||
|
assert!(deserialize_point(&pt).is_ok());
|
||||||
|
assert!(EdwardsPoint::from_element_slice(GenericArray::from_slice(&pt)).is_err());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user