Skip to content

Instantly share code, notes, and snippets.

@hellman
Created June 18, 2017 22:04
Show Gist options
  • Save hellman/1c0f423e50ad792db6fba16301596f6f to your computer and use it in GitHub Desktop.
Save hellman/1c0f423e50ad792db6fba16301596f6f to your computer and use it in GitHub Desktop.
Google CTF 2017 Quals - Shake It
#[macro_use]
extern crate arrayref;
extern crate crypto;
use crypto::aead::AeadDecryptor;
use crypto::chacha20poly1305::ChaCha20Poly1305;
use std::env;
use std::fs::File;
use std::io::{Read, Write};
fn main() {
// sick rust skills..
let pub1: [u8; 32] = [126,135,43,154,233,112,76,202,2,52,240,114,242,64,55,38,130,22,144,120,124,170,192,48,245,44,247,82,99,39,157,10];
let pub2: [u8; 32] = [42,79,214,40,69,94,71,17,96,199,42,48,175,22,243,139,105,139,165,132,83,201,248,247,235,61,155,219,160,135,218,8];
let nonce: [u8; 8] = [109,122,162,189,164,197,151,21];
let mut tag: [u8; 16] = [218,74,225,160,87,120,12,92,159,247,79,67,13,37,169,63];
let ct: [u8; 44] = [230,101,167,226,90,21,144,243,89,153,197,67,122,232,189,238,172,4,200,34,73,34,188,36,162,91,39,144,128,52,97,16,82,96,14,36,39,190,212,75,7,247,114,150];
let sk: [u8; 32] = [24,79,211,254,185,245,184,126,203,154,128,238,220,240,144,178,246,28,156,187,92,111,50,53,36,36,74,200,235,90,58,197];
let mut plain: [u8; 44] = [0; 44];
let mut cipher: [u8; 44] = [0; 44];
let mut ad = ChaCha20Poly1305::new(&sk, &nonce, &[]);
ad.decrypt(&ct, &mut plain, &tag);
let mut output_file = File::create("output").unwrap();
output_file.write_all(&plain).unwrap();
}
// CTF{reallly??SomeGroupAreBetterThanOthers?}
#-*- coding:utf-8 -*-
'''
kex.rs implements exponentiation in GF(2**252).
Just map bits properly and call Sage's discrete_log.
It has good algorithms for such fields.
'''
from sage.all import *
from pyblake2 import blake2b
def bytes2poly(mod):
npoly = sum(v*(256**e) for e, v in enumerate(mod))
return sum(c*X**e for e, c in enumerate(Integer(npoly).bits()))
def poly2bytes(poly):
mod = sum(int(poly[i])*(1 << i) for i in xrange(poly.degree() + 1))
return [(mod >> (i * 8)) & 0xff for i in xrange(32)]
X = GF(2).polynomial_ring().gen()
mod = [0x09, 0x82, 0x3b, 0xad, 0x5d, 0xc5, 0xea, 0xda, 0x33, 0xa6, 0x1b, 0x93, 0x69, 0x82,
0xd3, 0xca, 0x18, 0x3b, 0x98, 0x18, 0x48, 0xe8, 0x66, 0xd2, 0x17, 0x2d, 0xd3, 0xe5,
0xaa, 0xd3, 0x2d, 0x1b]
poly = bytes2poly(mod)
enc = open("flag.txt.enc").read()
pub1 = map(ord, enc[:32])
pub2 = map(ord, enc[32:64])
nonce = enc[64:72]
tag = enc[72:88]
ct = enc[88:]
F = GF(2**poly.degree(), modulus=poly, name='a')
fpub1 = F(bytes2poly(pub1))
fpub2 = F(bytes2poly(pub2))
ans1 = discrete_log(fpub1, F.gen())
# ans1 = 3296127762875791627182363440284922248840950011248587916702578888149075502693
print "ANS1", ans1
ans2 = discrete_log(fpub2, F.gen())
# ans2 = 1822857624232553449170040157676658859943351503055490090154504222511989687747
print "ANS2", ans2
assert fpub1 ** ans2 == fpub2 ** ans1
sk = fpub1 ** ans2
sk = poly2bytes(sk.polynomial())
data = "".join(map(chr, pub1))
data += "".join(map(chr, pub2))
data += "".join(map(chr, sk))
sk = blake2b(data, digest_size=32).digest()
def encode(x):
return ",".join(map(str, map(ord, x)))
print "let pub1: [u8; %d] = [%s];" % (len(pub1), encode("".join(map(chr, pub1))))
print "let pub2: [u8; %d] = [%s];" % (len(pub2), encode("".join(map(chr, pub2))))
print "let nonce: [u8; %d] = [%s];" % (len(nonce), encode(nonce))
print "let tag: [u8; %d] = [%s];" % (len(tag), encode(tag))
print "let ct: [u8; %d] = [%s];" % (len(ct), encode(ct))
print "let sk: [u8; %d] = [%s];" % (len(sk), encode(sk))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment