Skip to content

Commit a270dd4

Browse files
committed
surprise: refined
1 parent 9d734ca commit a270dd4

6 files changed

Lines changed: 315 additions & 243 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

assets/surprise.bin

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:16da91bf5ce6b106c26068afc0355b2141ab54adedd739c1ef9d06968a12dfff
3-
size 43
2+
oid sha256:d7783e2b901075fda76316d9bb1008f7bfd7e4257727c18872bf77e3cfa1b62a
3+
size 280

surprise.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
key = "x^6"
1+
key = "x^8 +x^7 + x^6 + x^5"
22
payload = "A very secret surprise message!"

web_app/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ tokenizers = { version = "0.22", optional = true }
6767
mistralrs = { version = "0.7", optional = true }
6868
rssn = { version = "0.2", features = ["full"], optional = true }
6969
num-bigint = "0.4"
70+
num-traits = "0.2"
7071
bincode-next = { version = "2.0", features = ["serde"] }
7172
clap = { version = "4.5", features = ["cargo", "derive", "env"] }
7273
memmap2 = "0.9"
@@ -138,6 +139,7 @@ site-addr = "0.0.0.0:8088"
138139
toml = "0.9"
139140
serde = { version = "1.0", features = ["derive"] }
140141
num-bigint = "0.4"
142+
num-traits = "0.2"
141143
bincode-next = { version = "2.0", features = ["serde"] }
142144
tokenizers = { version = "0.22" }
143145
serde_json = "1.0"

web_app/build.rs

Lines changed: 102 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::sync::Arc;
33

44
use num_bigint::BigInt;
55
use num_bigint::Sign;
6+
use num_traits::ToPrimitive;
67
use rssn::symbolic::calculus::differentiate;
78
use rssn::symbolic::calculus::substitute;
89
use rssn::symbolic::core::Expr;
@@ -252,6 +253,7 @@ fn main() -> Result<
252253
deriv = simplify(&deriv)
253254
.to_ast()
254255
.map_err(|e| {
256+
255257
format!(
256258
"to_ast failed: {}",
257259
e
@@ -260,36 +262,54 @@ fn main() -> Result<
260262

261263
deriv = force_bigint(deriv);
262264

263-
// Convert payload to BigInt
264-
let payload_num =
265-
BigInt::from_bytes_be(
266-
Sign::Plus,
267-
surprise
268-
.payload
269-
.as_bytes(),
265+
// Convert payload to BigInt in chunks (1 byte per chunk for maximum safety)
266+
let payload_bytes = surprise
267+
.payload
268+
.as_bytes();
269+
270+
let chunk_size = 1;
271+
272+
let mut results = Vec::new();
273+
274+
for chunk in payload_bytes
275+
.chunks(chunk_size)
276+
{
277+
278+
// Prepend a 1 byte to distinguish from trailing zeros and keep x > 255
279+
let mut chunk_with_sentinel =
280+
vec![1u8];
281+
282+
chunk_with_sentinel
283+
.extend_from_slice(
284+
chunk,
285+
);
286+
287+
let p = BigInt::from_bytes_be(Sign::Plus, &chunk_with_sentinel);
288+
289+
// Evaluate at P
290+
let eval_expr = substitute(
291+
&deriv,
292+
"x",
293+
&Expr::BigInt(p),
270294
);
271295

272-
// Evaluate at P
273-
// result = f(P)
274-
let eval_expr = substitute(
275-
&deriv,
276-
"x",
277-
&Expr::BigInt(payload_num),
278-
);
296+
let r =
297+
simplify(&eval_expr)
298+
.to_ast()
299+
.map_err(|e| {
279300

280-
let result_expr = simplify(
281-
&eval_expr,
282-
)
283-
.to_ast()
284-
.map_err(|e| {
285-
format!(
286-
"to_ast failed: {}",
287-
e
288-
)
289-
})?;
301+
format!(
302+
"to_ast failed: {}",
303+
e
304+
)
305+
})?;
290306

291-
let result_expr =
292-
force_bigint(result_expr);
307+
// Aggressively force evaluation of numeric parts
308+
let evaled =
309+
force_bigint_eval(r);
310+
311+
results.push(evaled);
312+
}
293313

294314
// Serialize
295315
let assets_dir =
@@ -307,7 +327,7 @@ fn main() -> Result<
307327
Path::new(assets_dir)
308328
.join("surprise.bin");
309329

310-
let encoded: Vec<u8> = bincode_next::serde::encode_to_vec(&result_expr, bincode_next::config::standard())
330+
let encoded: Vec<u8> = bincode_next::serde::encode_to_vec(&results, bincode_next::config::standard())
311331
.map_err(|e| format!("Failed to encode: {}", e))?;
312332

313333
std::fs::write(
@@ -411,3 +431,58 @@ fn force_bigint(expr: Expr) -> Expr {
411431
| _ => expr,
412432
}
413433
}
434+
435+
fn force_bigint_eval(
436+
expr: Expr
437+
) -> Expr {
438+
439+
match expr {
440+
Expr::Constant(f) if f.fract() == 0.0 => Expr::BigInt(num_bigint::BigInt::from(f as i64)),
441+
Expr::Add(a, b) => {
442+
let left = force_bigint_eval(a.as_ref().clone());
443+
let right = force_bigint_eval(b.as_ref().clone());
444+
match (left, right) {
445+
(Expr::BigInt(va), Expr::BigInt(vb)) => Expr::BigInt(va + vb),
446+
(la, ra) => Expr::Add(Arc::new(la), Arc::new(ra)),
447+
}
448+
}
449+
Expr::Sub(a, b) => {
450+
let left = force_bigint_eval(a.as_ref().clone());
451+
let right = force_bigint_eval(b.as_ref().clone());
452+
match (left, right) {
453+
(Expr::BigInt(va), Expr::BigInt(vb)) => Expr::BigInt(va - vb),
454+
(la, ra) => Expr::Sub(Arc::new(la), Arc::new(ra)),
455+
}
456+
}
457+
Expr::Mul(a, b) => {
458+
let left = force_bigint_eval(a.as_ref().clone());
459+
let right = force_bigint_eval(b.as_ref().clone());
460+
match (left, right) {
461+
(Expr::BigInt(va), Expr::BigInt(vb)) => Expr::BigInt(va * vb),
462+
(la, ra) => Expr::Mul(Arc::new(la), Arc::new(ra)),
463+
}
464+
}
465+
Expr::Power(a, b) => {
466+
let left = force_bigint_eval(a.as_ref().clone());
467+
let right = force_bigint_eval(b.as_ref().clone());
468+
match (left, right) {
469+
(Expr::BigInt(base), Expr::BigInt(exp)) => {
470+
if let Some(e) = exp.to_u32() {
471+
Expr::BigInt(base.pow(e))
472+
} else {
473+
Expr::Power(Arc::new(Expr::BigInt(base)), Arc::new(Expr::BigInt(exp)))
474+
}
475+
}
476+
(la, ra) => Expr::Power(Arc::new(la), Arc::new(ra)),
477+
}
478+
}
479+
Expr::Neg(a) => {
480+
let inner = force_bigint_eval(a.as_ref().clone());
481+
match inner {
482+
Expr::BigInt(v) => Expr::BigInt(-v),
483+
other => Expr::Neg(Arc::new(other)),
484+
}
485+
}
486+
_ => expr,
487+
}
488+
}

0 commit comments

Comments
 (0)