std::vector<VoxelClusterSegment> VoxelShredder::shred(const std::vector<glm::uvec3> & input, const glm::uvec3 & llf, const glm::uvec3 & urb, u32 depth ) { const auto inputCenter = (glm::vec3(llf) + glm::vec3(urb)) / 2.0f; const auto separationPlaneNormal = RandomUnitVec3(); const auto separationPlaneD = glm::dot(separationPlaneNormal, inputCenter); std::vector<glm::uvec3> left; std::vector<glm::uvec3> right; auto leftLlf = glm::uvec3(std::numeric_limits<u32>::max()); auto leftUrb = glm::uvec3(0); auto rightLlf = leftLlf; auto rightUrb = leftUrb; for (const auto & cell : input) { const auto position = glm::vec3(cell); if (glm::dot(position, separationPlaneNormal) > separationPlaneD) { leftLlf = glm::min(cell, leftLlf); leftUrb = glm::max(cell, leftUrb); left.emplace_back(cell); } else { rightLlf = glm::min(cell, rightLlf); rightUrb = glm::max(cell, rightUrb); right.emplace_back(cell); } } if (depth < m_maxShredDepth) { auto leftShredded = shred(left, leftLlf, leftUrb, depth + 1); auto rightShredded = shred(right, rightLlf, rightUrb, depth + 1); std::vector<VoxelClusterSegment> result; result.resize(leftShredded.size() + rightShredded.size()); std::copy(leftShredded.begin(), leftShredded.end(), result.begin()); std::copy(rightShredded.begin(), rightShredded.end(), result.begin() + leftShredded.size()); return result; } else { std::vector<VoxelClusterSegment> result; if (!left.empty()) result.emplace_back(VoxelClusterSegment{left, leftLlf, leftUrb}); if (!right.empty()) result.emplace_back(VoxelClusterSegment{right, rightLlf, rightUrb}); return result; } }
void free_code(struct jit* jit, lua_State* L, cfunction func) { size_t i; struct jit_head* h = ((struct jit_head*) func) - 1; for (i = 0; i < jit->pagenum; i++) { struct page* p = jit->pages[i]; if ((uint8_t*) h < (uint8_t*) p || (uint8_t*) p + p->size <= (uint8_t*) h) { continue; } luaL_unref(L, LUA_REGISTRYINDEX, h->ref); EnableWrite(p, p->size); p->freed += h->size; shred(h, 0, h->size); if (p->freed < p->off) { EnableExecute(p, p->size); return; } FreePage(p, p->size); memmove(&jit->pages[i], &jit->pages[i+1], (jit->pagenum - (i+1)) * sizeof(jit->pages[0])); jit->pagenum--; return; } assert(!"couldn't find func in the jit pages"); }
std::vector<VoxelClusterSegment> VoxelShredder::shred(const VoxelCluster<u32> & input) { std::vector<glm::uvec3> voxels; voxels.reserve(input.numVoxels()); for (size_t v = 0; v < input.voxels().size(); ++v) { if (input.test(v)) voxels.emplace_back(input.indexToVoxel(v)); } return shred(voxels, {0, 0, 0}, input.size(), 0); }
std::vector<Entity> VoxelShredder::shred(const Entity & originalEntity) { auto segments = shred(originalEntity.component<VoxelObject>().data()->colorIndices()); std::vector<Entity> result; result.reserve(segments.size()); for (auto & segment : segments) { auto entity = VoxelClusterSplitSystem::splitVoxelsOffEntity(originalEntity, segment); result.emplace_back(entity); } return result; }
static void* reserve_code(struct jit* jit, lua_State* L, size_t sz) { struct page* page; size_t off = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->off : 0; size_t size = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->size : 0; if (off + sz >= size) { int i; uint8_t* pdata; cfunction func; /* need to create a new page */ jit->pages = (struct page**) realloc(jit->pages, (++jit->pagenum) * sizeof(jit->pages[0])); size = ALIGN_UP(sz + LINKTABLE_MAX_SIZE + sizeof(struct page), jit->align_page_size); page = (struct page*) AllocPage(size); jit->pages[jit->pagenum-1] = page; pdata = (uint8_t*) page; page->size = size; page->off = sizeof(struct page); lua_newtable(L); #define ADDFUNC(DLL, NAME) \ lua_pushliteral(L, #NAME); \ func = DLL ? (cfunction) GetProcAddressA(DLL, #NAME) : NULL; \ func = func ? func : (cfunction) &NAME; \ lua_pushcfunction(L, (lua_CFunction) func); \ lua_rawset(L, -3) ADDFUNC(NULL, check_double); ADDFUNC(NULL, check_float); ADDFUNC(NULL, check_uint64); ADDFUNC(NULL, check_int64); ADDFUNC(NULL, check_int32); ADDFUNC(NULL, check_uint32); ADDFUNC(NULL, check_uintptr); ADDFUNC(NULL, check_enum); ADDFUNC(NULL, check_typed_pointer); ADDFUNC(NULL, check_typed_cfunction); ADDFUNC(NULL, check_complex_double); ADDFUNC(NULL, check_complex_float); ADDFUNC(NULL, unpack_varargs_stack); ADDFUNC(NULL, unpack_varargs_stack_skip); ADDFUNC(NULL, unpack_varargs_reg); ADDFUNC(NULL, unpack_varargs_float); ADDFUNC(NULL, unpack_varargs_int); ADDFUNC(NULL, push_cdata); ADDFUNC(NULL, push_int); ADDFUNC(NULL, push_uint); ADDFUNC(NULL, lua_pushinteger); ADDFUNC(NULL, push_float); ADDFUNC(jit->kernel32_dll, SetLastError); ADDFUNC(jit->kernel32_dll, GetLastError); ADDFUNC(jit->lua_dll, luaL_error); ADDFUNC(jit->lua_dll, lua_pushnumber); ADDFUNC(jit->lua_dll, lua_pushboolean); ADDFUNC(jit->lua_dll, lua_gettop); ADDFUNC(jit->lua_dll, lua_rawgeti); ADDFUNC(jit->lua_dll, lua_pushnil); ADDFUNC(jit->lua_dll, lua_callk); ADDFUNC(jit->lua_dll, lua_settop); ADDFUNC(jit->lua_dll, lua_remove); //CHANGES: BEGIN ADDFUNC(jit->lua_dll, lua_pushlightuserdata); //CHANGES: END #undef ADDFUNC for (i = 0; extnames[i] != NULL; i++) { if (strcmp(extnames[i], "FUNCTION") == 0) { shred(pdata + page->off, 0, JUMP_SIZE); jit->function_extern = i; } else { lua_getfield(L, -1, extnames[i]); func = (cfunction) lua_tocfunction(L, -1); if (func == NULL) { luaL_error(L, "internal error: missing link for %s", extnames[i]); } compile_extern_jump(jit, L, func, pdata + page->off); lua_pop(L, 1); } page->off += JUMP_SIZE; } page->freed = page->off; lua_pop(L, 1); } else { page = jit->pages[jit->pagenum-1]; EnableWrite(page, page->size); } return (uint8_t*) page + page->off; }
int pq_gen_key( PQ_PARAM_SET *P, size_t *privkey_blob_len, unsigned char *privkey_blob, size_t *pubkey_blob_len, unsigned char *pubkey_blob) { uint16_t i; uint16_t m; uint16_t N; uint16_t padN; int64_t q; int8_t p; uint16_t d1; uint16_t d2; uint16_t d3; size_t private_key_blob_len; size_t public_key_blob_len; uint16_t *f; uint16_t *g; int64_t *h; size_t scratch_len; size_t offset; unsigned char *scratch; int64_t *a1; int64_t *a2; int64_t *tmpx3; if(!P || !privkey_blob_len || !pubkey_blob_len) { return PQNTRU_ERROR; } N = P->N; padN = P->padded_N; q = P->q; p = P->p; d1 = P->d1; d2 = P->d2; d3 = P->d3; /* TODO: Standardize packed key formats */ private_key_blob_len = PRIVKEY_PACKED_BYTES(P); public_key_blob_len = PUBKEY_PACKED_BYTES(P); if(!privkey_blob || !pubkey_blob) { if(!privkey_blob && privkey_blob_len != NULL) { *privkey_blob_len = private_key_blob_len; } if(!pubkey_blob && pubkey_blob_len != NULL) { *pubkey_blob_len = public_key_blob_len; } return PQNTRU_OK; } if((*privkey_blob_len != private_key_blob_len) || (*pubkey_blob_len != public_key_blob_len)) { return PQNTRU_ERROR; } scratch_len = 2 * PRODUCT_FORM_BYTES(P) + 6 * POLYNOMIAL_BYTES(P); if(!(scratch = malloc(scratch_len))) { return PQNTRU_ERROR; } memset(scratch, 0, scratch_len); offset = 0; f = (uint16_t*)(scratch); offset += PRODUCT_FORM_BYTES(P); g = (uint16_t*)(scratch + offset); offset += PRODUCT_FORM_BYTES(P); h = (int64_t*)(scratch + offset); offset += POLYNOMIAL_BYTES(P); a1 = (int64_t*)(scratch + offset); offset += POLYNOMIAL_BYTES(P); a2 = (int64_t*)(scratch + offset); offset += POLYNOMIAL_BYTES(P); tmpx3 = (int64_t*)(scratch + offset); /* Find invertible pf mod q */ /* TODO: Better sampling of product form keys * Try to avoid keys with f(1) = 0 */ do { pol_gen_product(f, d1, d2, d3, N); /* f = p * (1 + product form poly) */ memset(a1, 0, POLYNOMIAL_BYTES(P)); a1[0] = p; pol_mul_product(a1, a1, d1, d2, d3, f, N, tmpx3); a1[0] += p; } while(PQNTRU_ERROR == pol_inv_mod2(a2, a1, N)); /* Lift from (Z/2Z)[X]/(X^N - 1) to (Z/qZ)[X]/(X^N -1) */ for (m = 0; m < 5; ++m) /* assumes 2^16 < q <= 2^32 */ { /* a^-1 = a^-1 * (2 - a * a^-1) mod q */ pol_mul_product(a1, a2, d1, d2, d3, f, N, tmpx3); for (i = 0; i < N; ++i) { a1[i] = -p*(a1[i] + a2[i]); } a1[0] = a1[0] + 2; pol_mul_coefficients(a2, a2, a1, N, padN, q, tmpx3); } /* Find invertible g mod p */ do { /* Generate product form g, * then expand it to find inverse mod p */ pol_gen_product(g, d1, d2, d3, N); memset(a1, 0, POLYNOMIAL_BYTES(P)); a1[0] = 1; pol_mul_product(a1, a1, d1, d2, d3, g, N, tmpx3); a1[0] += 1; } while(PQNTRU_ERROR == pol_inv_modp(tmpx3, a1, N, p)); pack_private_key(P, f, g, tmpx3, private_key_blob_len, privkey_blob); /* Calculate public key, h = g/f mod q */ pol_mul_product(h, a2, d1, d2, d3, g, N, tmpx3); for(i=0; i<N; i++) { h[i] = cmod(h[i] + a2[i], q); } /* int j; for (i=0; i<d1; i++) { for (j=d1; j<2*d1; j++) { if (f[i] == f[j]) { printf("stupid key f: %d, %d, %d!\n", i, j, f[i]); break; } if (g[i] == g[j]) { printf("stupid key g: %d, %d, %d!\n", i, j, g[i]); break; } } } for (i=2*d1; i<2*d1+d2; i++) { for (j=2*d1+d2; j<2*(d1+d2); j++) { if (f[i] == f[j]) { printf("stupid key f: %d, %d, %d!\n", i, j, f[i]); break; } if (g[i] == g[j]) { printf("stupid key g: %d, %d, %d!\n", i, j, g[i]); break; } } } for (i=2*(d1+d2); i<2*(d1+d2)+d3; i++) { for (j=2*(d1+d2)+d3; j<2*(d1+d2+d3); j++) { if (f[i] == f[j]) { printf("stupid key f: %d, %d, %d!\n", i, j, f[i]); break; } if (g[i] == g[j]) { printf("stupid key g: %d, %d, %d!\n", i, j, g[i]); break; } } }*/ pack_public_key(P, h, public_key_blob_len, pubkey_blob); shred(scratch, scratch_len); free(scratch); return PQNTRU_OK; }
int pq_sign( size_t *packed_sig_len, unsigned char *packed_sig, const size_t private_key_len, const unsigned char *private_key_blob, const size_t public_key_len, const unsigned char *public_key_blob, const size_t msg_len, const unsigned char *msg) { uint16_t i; int error = 0; uint16_t N; uint16_t padN; int64_t q; int8_t p; uint16_t d1; uint16_t d2; uint16_t d3; int64_t m; size_t scratch_len; unsigned char *scratch; size_t offset; uint16_t *f; /* Private key product form f indices */ uint16_t *g; /* .. product form g indices */ int64_t *ginv; /* Private key; coefficients of g^{-1} */ int64_t *h; /* Public key coefficients */ int64_t *s0; /* scratch space for random lattice point */ int64_t *t0; int64_t *a; /* scratch space for 3 polynomials */ int64_t *tmpx2;/* scratch space for 2 polynomials (aliased by a) */ int8_t *sp; /* Document hash */ int8_t *tp; PQ_PARAM_SET *P; int rc = PQNTRU_OK; if(!private_key_blob || !public_key_blob || !packed_sig_len) { return PQNTRU_ERROR; } rc = get_blob_params(&P, private_key_len, private_key_blob); if(PQNTRU_ERROR == rc) { return PQNTRU_ERROR; } if(!packed_sig) /* Return signature size in packed_sig_len */ { *packed_sig_len = SIGNATURE_BYTES(P); return PQNTRU_OK; } if(!msg || msg_len == 0) { return PQNTRU_ERROR; } N = P->N; padN = P->padded_N; q = P->q; p = P->p; d1 = P->d1; d2 = P->d2; d3 = P->d3; scratch_len = 2 * PRODUCT_FORM_BYTES(P) /* f and g */ + 7 * POLYNOMIAL_BYTES(P) /* h, ginv, and 5 scratch polys */ + 2 * N; /* sp, tp */ if(!(scratch = malloc(scratch_len))) { return PQNTRU_ERROR; } memset(scratch, 0, scratch_len); offset = 0; f = (uint16_t*)(scratch); offset += PRODUCT_FORM_BYTES(P); g = (uint16_t*)(scratch + offset); offset += PRODUCT_FORM_BYTES(P); h = (int64_t*)(scratch + offset); offset += POLYNOMIAL_BYTES(P); ginv = (int64_t*)(scratch + offset); offset += POLYNOMIAL_BYTES(P); s0 = (int64_t*)(scratch + offset); offset += POLYNOMIAL_BYTES(P); t0 = (int64_t*)(scratch + offset); offset += POLYNOMIAL_BYTES(P); /* a is treated as 3 polynomials, aliases tmpx2 */ a = (int64_t*)(scratch + offset); offset += POLYNOMIAL_BYTES(P); tmpx2= (int64_t*)(scratch + offset); offset += 2* POLYNOMIAL_BYTES(P); sp = (int8_t*)(scratch + offset); offset += N; tp = (int8_t*)(scratch + offset); /* Unpack the keys */ rc = unpack_private_key(P, f, g, ginv, private_key_len, private_key_blob); if(PQNTRU_ERROR == rc) { shred(scratch, scratch_len); free(scratch); return PQNTRU_ERROR; } rc = unpack_public_key(P, h, public_key_len, public_key_blob); if(PQNTRU_ERROR == rc) { shred(scratch, scratch_len); free(scratch); return PQNTRU_ERROR; } /* Generate a document hash to sign */ challenge(sp, tp, public_key_len, public_key_blob, msg_len, msg); int64_t *t = (int64_t *)malloc(N*sizeof(int64_t)); int64_t *s = (int64_t *)malloc(N*sizeof(int64_t)); do { error = 0; /* Choose random s0 satisfying s0 = sp (mod p) */ pol_unidrnd_pZ(s0, N, q, p); for(i=0; i<N; i++) { s0[i] += sp[i]; } /* Load h into a zero padded polynomial */ memcpy(t0, h, N*sizeof(int64_t)); /* t0 = h*s0 */ pol_mul_coefficients(t0, t0, s0, N, padN, q, a); /* t0 = tp - (s0*h) */ for(i=0; i<N; i++) { t0[i] *= -1; t0[i] += tp[i]; } /* a = ginv * (tp - t0) (mod p) */ pol_mul_coefficients(a, t0, ginv, N, padN, p, a); /* tmpx2 = a * F = (a * (f-1)/p) */ pol_mul_product(tmpx2, a, d1, d2, d3, f, N, tmpx2); for(i=0; i<N; i++) { m = p * (a[i] + tmpx2[i]); error |= (m > P->B_s) || (-m > P->B_s); s[i] = m; /* s0 = s0 + p*(a + tmpx2) = s0 + a*f */ s0[i] += m; error |= (cmod(s0[i], p) - sp[i]); /* Not necessary to check this */ error |= (s0[i] > P->norm_bound_s) || (-s0[i] > P->norm_bound_s); } /* tmpx2 = a * G = (a * (g - 1)) */ pol_mul_product(tmpx2, a, d1, d2, d3, g, N, tmpx2); for(i=0; i<N; i++) { m = (a[i] + tmpx2[i]); error |= (m > P->B_t) || (-m > P->B_t); t[i] = m; /* t0 = (a + tmpx2) - t0 + tp = a*g - tp + s0*h + tp = s0*h + a*g */ t0[i] = m - t0[i] + tp[i]; error |= (cmod(t0[i], p) - tp[i]); /* Not necessary to check this */ error |= (t0[i] > P->norm_bound_t) || (-t0[i] > P->norm_bound_t) ; } // attempts ++; } while(0 != error); for (i=0; i<N; i++) { if (s[i] > P->B_s || -s[i] > P->B_s) printf("s\tholy shit\n"); if (t[i] > P->B_t || -t[i] > P->B_t) printf("t\tholy shit\n"); } for(i=0; i<N; i++) { s0[i] = (s0[i] - sp[i])/P->p; s0[i] += P->q / (2*P->p); } pack_signature(P, s0, *packed_sig_len, packed_sig); shred(scratch, scratch_len); free(scratch); return PQNTRU_OK; }