Intro To Cryptography - Chapter 6
Problem 6.2
Check that the points and are points on the elliptic curve .
Solution:
(a) Compute the points and .
Solution: Using Theorem 6.6:
To calculate we use the same algorithm for , but with :
(b) Compute the points and .
Solution:
(bonus) How many points with integer coordinates can you find on ?
Solution: Well, via enumeration we can find some smaller ones:
It's clear from the equation for that there are no more negative values of that lie on . For finding more in the positive direction, I couldn't find a good analytic solution, so instead I brute forced it (see fn problem6_2
in the appendix) and found three additional points:
Problem 6.5
For each of the following elliptic curves and finite fields , make a list of the set of points .
(a) over .
Solution: First writing out the list of squares in
we plug in all possible values into the RHS and keep those which match the squares, in addition to the special point at :
(b) over .
Solution: Using the same approach,
Plugging in all possible values for , there's only two values , that lead to perfect squares. So all the points on are:
(c) over .
Solution: Using the same strategy and the table of squares from part (b), we find the points on are
Problem 6.8
Let be the elliptic curve
and let and be points on modulo . Solve the elliptic curve discrete logarithm for and . That is, find a positive integer such that .
Solution: Let's just enumerate :
:
:
:
Note that we have now found , however we do not know the size of nor the order of , so we can't easily use this information to find . So let's continue:
:
Therefore .
Problem 6.14
Alice and Bob agree to use elliptic Diffie-Hellman key exchange with the prime, elliptic curve, and point:
(a) Alice sends Bob the point Bob decides to use the secret multiplier . What point should Bob send to Alice?
Solution: Using the program in the appendix, I found
(b) What is their secret shared value?
Solution: The shared value is
(c) How difficult is it for Eve to figure out Alice's secret multiplier ? If you know how to program, use a computer to find .
Solution: Since p is only , the size of is not too large, so we can just exhaustively loop until we find a value of that works. Doing so yields .
(d) Alice and Bob decide to exchange a new piece of secret information using the same prime, curve, and point. This time Alice sends Bob only the -coordinate of her point . Bob decides to use the secret multiplier . What single number modulo should Bob send to Alice, and what is their secret shared value?
Solution: Bob should send the number to Alice. Their secret shared value is .
Problem 6.16
A shortcoming of using an elliptic curve for cryptography is the fact that it takes two coordinates to specify a point in . However, the second coordinate actually conveys very little additional information.
(a) Suppose that Bob wants to send Alice the value of a point . Explain why it suffices for Bob to send Alice the -coordinate of together with the single bit
(You may assume Alice is able to efficiently compute square roots modulo .)
Solution: The tuple is enough to identify the point on because there are only two points that share the same -coordinate: and . Furthermore, in we have
that is, we can say that those values less than are the "positive" numbers and the ones greater than are the "negative" numbers. This way, we only need one bit of information which informs which one of the two possible values (i.e. the positive or negative one) we want to convey. (Small note that we're assuming is some large prime, so it is odd, and we don't have to worry about equality on the boundary.)
Thus, Alice simply needs to plug the value into the equation for and she can find the value . After this she computes the square root (if then she can just compute ) to find . She then chooses the that satisfies the condition.
(b) Alice and Bob decide to use the prime and the elliptic curve
Bob sends Alice the -coordinate and the bit . What point is Bob trying to convey to Alice? What about if instead Bob had sent ?
Solution: When , Bob is trying to convey the point . When , the point conveyed is .
Appendix
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Point {
Coord(u64, u64),
Zero,
}
pub struct Curve {
pub p: u64,
pub a: u64,
pub b: u64,
pub pk: Point,
}
impl Curve {
/// Make an n multiple of a point, using the doulbe-and-add algorithm
fn multiple(&self, n: u64, pt: Point) -> Point {
let mut n = n;
let mut q = pt;
let mut r = Point::Zero;
while n > 0 {
if n % 2 == 1 {
r = self.add(r, q);
}
q = self.add(q, q);
n /= 2;
}
r
}
/// Add two points together
fn add(&self, p1: Point, p2: Point) -> Point {
match (p1, p2) {
(Point::Zero, _) => p2,
(_, Point::Zero) => p1,
(Point::Coord(x1, y1), Point::Coord(x2, y2)) if x1 == x2 && y1 == self.neg(y2) => {
Point::Zero
}
(Point::Coord(x1, y1), Point::Coord(x2, y2)) => {
let lambda = if p1 != p2 {
(y2 + self.neg(y1)) * self.inv(x2 + self.neg(x1))
} else {
(3 * (x1 * x1) + self.a) * self.inv(2 * y1)
} % self.p;
let x3 = ((lambda * lambda) + self.neg(x1) + self.neg(x2)) % self.p;
let y3 = (lambda * (x1 + self.neg(x3)) + self.neg(y1)) % self.p;
Point::Coord(x3, y3)
}
}
}
/// Return the "positive" y coordinate of E at the given x.
fn eval_at(&self, x: u64) -> u64 {
let y_sq = (x * x * x) + self.a * x + self.b % self.p;
assert_eq!(
self.p % 4,
3,
"this method does not work unless p = 3 mod 4"
);
mod_pow(y_sq, (self.p + 1) / 4, self.p)
}
/// Get additive inverse mod p.
fn neg(&self, x: u64) -> u64 {
(self.p - x) % self.p
}
/// Get multiplicative inverse mod p.
fn inv(&self, x: u64) -> u64 {
crate::fast_inv(x, self.p)
}
}
fn mod_pow(base: u64, exp: u64, modulus: u64) -> u64 {
let mut out = 1;
for _ in 0..exp {
out = out * base % modulus
}
out
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn example_6_16() {
let curve = Curve {
p: 3623,
a: 14,
b: 19,
pk: Point::Coord(6, 730),
};
let n = 947;
assert_eq!(curve.multiple(n, curve.pk), Point::Coord(3492, 60))
}
#[test]
fn problem6_14_a() {
let curve = Curve {
p: 2671,
a: 171,
b: 853,
pk: Point::Coord(1980, 431),
};
let n = 1943;
assert_eq!(curve.multiple(n, curve.pk), Point::Coord(1432, 667))
}
#[test]
fn problem6_14_b() {
let curve = Curve {
p: 2671,
a: 171,
b: 853,
pk: Point::Coord(1980, 431),
};
let n = 1943;
let q = Point::Coord(2110, 543);
assert_eq!(curve.multiple(n, q), Point::Coord(2424, 911))
}
#[test]
fn problem6_14_c() {
let curve = Curve {
p: 2671,
a: 171,
b: 853,
pk: Point::Coord(1980, 431),
};
let q = Point::Coord(2110, 543);
let n = (1..).find(|&n| curve.multiple(n, curve.pk) == q).unwrap();
assert_eq!(n, 726);
}
#[test]
fn problem6_14_d() {
let curve = Curve {
p: 2671,
a: 171,
b: 853,
pk: Point::Coord(1980, 431),
};
let n = 875;
let qb = curve.multiple(n, curve.pk);
assert_eq!(qb, Point::Coord(161, 2040));
let qx = 2;
let qy = curve.eval_at(qx);
let q = Point::Coord(qx, qy);
let secret = curve.multiple(n, q);
assert_eq!(secret, Point::Coord(1708, 1419));
}
#[test]
fn problem6_16_b() {
let curve = Curve {
p: 1123,
a: 54,
b: 87,
pk: Point::Zero,
};
let y_pos = curve.eval_at(278);
assert_eq!(y_pos, 487);
let y_neg = curve.p - y_pos;
assert_eq!(y_neg, 636);
}
#[test]
fn problem6_2() {
let e = |x: u64| x.checked_pow(3).and_then(|x3| x3.checked_add(17));
let mut sols = vec![];
// For x > 0, y is increasing as a function of x, so once we find the
// smallest x such that e(x) >= y^2, we can start the search for (y+1)^2
// at e(x).
let mut x: u64 = 0;
// Ran with u64::MAX first, then replaced with the max y value found.
for y in 1..=378661u64 {
let ys = match y.checked_mul(y) {
Some(ys) => ys,
None => break,
};
while matches!(e(x), Some(e) if e < ys) {
x += 1;
}
match e(x) {
Some(e) if e == ys => {
sols.push((x, y));
}
None => break,
_ => continue,
}
}
assert_eq!(
sols,
vec![
(2, 5),
(4, 9),
(8, 23),
(43, 282),
(52, 375),
(5234, 378661)
]
);
}
}