Skip to content

Commit

Permalink
Quartz sync: Sep 10, 2024, 10:49 AM
Browse files Browse the repository at this point in the history
  • Loading branch information
jackddouglas committed Sep 10, 2024
1 parent 9fab0ec commit d9ea5fc
Show file tree
Hide file tree
Showing 9 changed files with 470 additions and 42 deletions.
2 changes: 1 addition & 1 deletion content/Chinese Remainder Theorem.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ tags: []
## Constructing the Solution:
- Calculate $M=m_1*m_2*\dots *m_n$
- For each $i$, calculate $M_i=M/m_i c$
- Find the modular multiplicative inverse of $M_i$ modulo $m_i$, call it $y_i$ ($M_i y_i \equiv 1 \text{ (mod } m_i \text{)}$)
- Find the [[modular multiplicative inverse]] of $M_i$ modulo $m_i$, call it $y_i$ ($M_i y_i \equiv 1 \text{ (mod } m_i \text{)}$)
- The solution is: $x \equiv (a_1M_1y_1+a_2M_2y_2+\dots+a_nM_ny_n)$ (mod $M$).

## Why It Works
Expand Down
71 changes: 71 additions & 0 deletions content/Lagrange interpolation formula.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
id: 1725960857-lagrange-interpolation-formula
aliases:
- Lagrange interpolation formula
tags: []
---

# Lagrange interpolation formula
A mathematical method used to reconstruct a polynomial given a set of points. In the context of Shamir's Secret Sharing, it's used to reconstruct the secret from the shared points.

The general form of the Lagrange interpolation formula is:

```
f(x) = Σ(i=1 to n) yi * Li(x)
```

Where:
- `f(x)` is the reconstructed polynomial
- `yi` are the y-coordinates of the known points
- `Li(x)` are the Lagrange basis polynomials

In the [[1725904360-shamirs-secret-sharing|Shamir's Secret Sharing]] code, this formula is implemented as follows:

1. The outer loop `for i in 0..threshold` corresponds to the summation in the formula.

2. The `Li(x)` term is calculated in parts:
```rust
let mut numerator = BigInt::one();
let mut denominator = BigInt::one();

for j in 0..threshold {
if i != j {
let (xj, _) = &shares[j];
numerator *= xj.to_bigint().unwrap();
numerator %= &prime_int;
denominator *=
(xj.to_bigint().unwrap() - xi.to_bigint().unwrap() + &prime_int) % &prime_int;
denominator %= &prime_int;
}
}
```

This calculates:
```
Li(x) = Π(j≠i) (x - xj) / (xi - xj)
```

3. The `yi` term is multiplied in:
```rust
let term = yi.to_bigint().unwrap() * numerator * mod_inverse(&denominator, &prime_int);
```

4. Each term is added to the secret:
```rust
secret += term;
secret %= &prime_int;
```

In [[Shamir's Secret Sharing]]:
- The secret is the constant term of a polynomial.
- Shares are points on this polynomial.
- Reconstruction uses Lagrange interpolation to find the polynomial and extract the constant term (the secret).

The use of modular arithmetic (with a prime modulus) ensures:
1. The calculations are performed in a [[finite field]].
2. Security properties of the scheme are maintained.
3. All operations "wrap around" the prime, keeping values manageable.

This implementation is secure because:
- It requires a threshold number of shares to reconstruct.
- Without enough shares, the polynomial (and thus the secret) remains undetermined.
70 changes: 34 additions & 36 deletions content/Modular exponentiation.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,49 +8,47 @@ tags: []
# Modular exponentiation
Efficient algorithm to calculate (base^exp) % modulus.

The key idea is to break down the exponent into its binary representation and use the property that:

(a * b) mod m = ((a mod m) * (b mod m)) mod m

This allows the algorithm to perform the modulus operation at each step, keeping the intermediate results small and manageable.

## Rust Implementation
```rust
fn mod_pow(mut base: u64, mut exp: u64, modulus: u64) -> u64 {
if modulus == 1 {
return 0;
}

let mut result = 1;
base %= modulus;
while exp > 0 {
if exp % 2 == 1 {
result = mod_mul(result, base, modulus);
fn mod_pow(base: &BigUint, exp: &BigUint, modulus: &BigUint) -> BigUint {
let mut result = BigUint::one();
let mut base = base.clone();
let mut exp = exp.clone();
while exp > BigUint::zero() {
if exp.bit(0) {
result = (result * &base) % modulus;
}

base = (&base * &base) % modulus;
exp >>= 1;
base = mod_mul(base, base, modulus);
}
result
}

fn mod_mul(a: u64, b: u64, m: u64) -> u64 {
((a as u128 * b as u128) % m as u128) as u64
}
```
1. Function signature:
- Takes three `u64` parameters: `base`, `exp` (exponent), and `modulus`
- Returns a `u64` result

2. Edge case handling:
- If `modulus` is 1, it returns 0 (as any number mod 1 is 0)

3. Initialization:
- `result` is set to 1 (neutral element for multiplication)
- `base` is reduced modulo `modulus` to ensure it's smaller than `modulus`

4. Main loop:
- Continues while `exp` is greater than 0
- Uses the binary exponentiation algorithm:
- If the least significant bit of `exp` is 1, multiply `result` by `base`
- Divide `exp` by 2 (right shift by 1 bit)
- Square `base`
- All multiplications are done using modular arithmetic (via `mod_mul` function)

5. Return the final `result`
1. The function takes three parameters:
- `base`: The base number
- `exp`: The exponent
- `modulus`: The modulus for the operation
All parameters are references to `BigUint` (big unsigned integer) values.

2. Initialize `result` with 1 (BigUint::one()).

3. Clone `base` and `exp` to create mutable copies.

4. Enter a loop that continues while `exp` is greater than zero:

a. Check if the least significant bit of `exp` is 1 using `exp.bit(0)`.
If true, multiply `result` by `base` and take the modulus.

b. Square `base` and take the modulus.

c. Right-shift `exp` by 1 bit (equivalent to dividing by 2).

5. Return the final `result`.

This algorithm is efficient because it reduces the number of multiplications needed from O(exp) to O(log(exp)).
Loading

0 comments on commit d9ea5fc

Please sign in to comment.