firebase auth user photo URL returns 404 - ios
I've been using firebase authentication for a few months in a swift application, and suddenly today the app crashed due to the user photo URL leading to 404 page.
To get the picture I use:
let user = FIRAuth.auth()?.currentUser
userPhoto = user.photoURL?.absoluteString
The userPhoto URL leads to the broken robot 404 page, but only for one specific user.
When signing in to this problematic google account, the profile picture is displayed properly.
I tried signing out and back in, as well as changing the profile picture for the account.
Any ideas?
I don't know IOS/Swift but I am having same issue. It seems Firebase Auth caches photoURL's and I haven't been able to figure out how to force a refresh but a solution is to show a default image onerror. In javascript/HTML, it would look like below. NOTE: There is a CSS solution using :before and :after pseudo-classes for showing a custom fallback image but it's a bit hacky so I wrote this. I know it's not swift but maybe you can use it as a guide to coding something similar for IOS.
function returnPhotoURL(){
return new Promise(function(resolve, reject){
var img = new Image();
//if the user does not have a photoURL let's try and get one from gravatar
if (!firebase.auth().currentUser.photoURL) {
//first we have to see if user han an email
if(firebase.auth().currentUser.email){
//set sign-in-button background image to gravatar url
img.addEventListener('load', function() {
resolve (getGravatar(firebase.auth().currentUser.email, 48));
}, false);
img.addEventListener('error', function() {
resolve ('//rack.pub/media/fallbackImage.png');
}, false);
img.src = getGravatar(firebase.auth().currentUser.email, 48);
} else {
resolve ('//rack.pub/media/fallbackImage.png');
}
} else {
img.addEventListener('load', function() {
resolve (firebase.auth().currentUser.photoURL);
}, false);
img.addEventListener('error', function() {
resolve ('https://rack.pub/media/fallbackImage.png');
}, false);
img.src = firebase.auth().currentUser.photoURL;
}
});
}
function getGravatar(email, size) {
// MD5 (Message-Digest Algorithm) by WebToolkit
var MD5 = function(s) {
function L(k, d) {
return (k << d) | (k >>> (32 - d))
}
function K(G, k) {
var I, d, F, H, x;
F = (G & 2147483648);
H = (k & 2147483648);
I = (G & 1073741824);
d = (k & 1073741824);
x = (G & 1073741823) + (k & 1073741823);
if (I & d) {
return (x ^ 2147483648 ^ F ^ H)
}
if (I | d) {
if (x & 1073741824) {
return (x ^ 3221225472 ^ F ^ H)
}
else {
return (x ^ 1073741824 ^ F ^ H)
}
}
else {
return (x ^ F ^ H)
}
}
function r(d, F, k) {
return (d & F) | ((~d) & k)
}
function q(d, F, k) {
return (d & k) | (F & (~k))
}
function p(d, F, k) {
return (d ^ F ^ k)
}
function n(d, F, k) {
return (F ^ (d | (~k)))
}
function u(G, F, aa, Z, k, H, I) {
G = K(G, K(K(r(F, aa, Z), k), I));
return K(L(G, H), F)
}
function f(G, F, aa, Z, k, H, I) {
G = K(G, K(K(q(F, aa, Z), k), I));
return K(L(G, H), F)
}
function D(G, F, aa, Z, k, H, I) {
G = K(G, K(K(p(F, aa, Z), k), I));
return K(L(G, H), F)
}
function t(G, F, aa, Z, k, H, I) {
G = K(G, K(K(n(F, aa, Z), k), I));
return K(L(G, H), F)
}
function e(G) {
var Z;
var F = G.length;
var x = F + 8;
var k = (x - (x % 64)) / 64;
var I = (k + 1) * 16;
var aa = Array(I - 1);
var d = 0;
var H = 0;
while (H < F) {
Z = (H - (H % 4)) / 4;
d = (H % 4) * 8;
aa[Z] = (aa[Z] | (G.charCodeAt(H) << d));
H++
}
Z = (H - (H % 4)) / 4;
d = (H % 4) * 8;
aa[Z] = aa[Z] | (128 << d);
aa[I - 2] = F << 3;
aa[I - 1] = F >>> 29;
return aa
}
function B(x) {
var k = "",
F = "",
G, d;
for (d = 0; d <= 3; d++) {
G = (x >>> (d * 8)) & 255;
F = "0" + G.toString(16);
k = k + F.substr(F.length - 2, 2)
}
return k
}
function J(k) {
k = k.replace(/rn/g, "n");
var d = "";
for (var F = 0; F < k.length; F++) {
var x = k.charCodeAt(F);
if (x < 128) {
d += String.fromCharCode(x)
}
else {
if ((x > 127) && (x < 2048)) {
d += String.fromCharCode((x >> 6) | 192);
d += String.fromCharCode((x & 63) | 128)
}
else {
d += String.fromCharCode((x >> 12) | 224);
d += String.fromCharCode(((x >> 6) & 63) | 128);
d += String.fromCharCode((x & 63) | 128)
}
}
}
return d
}
var C = Array();
var P, h, E, v, g, Y, X, W, V;
var S = 7,
Q = 12,
N = 17,
M = 22;
var A = 5,
z = 9,
y = 14,
w = 20;
var o = 4,
m = 11,
l = 16,
j = 23;
var U = 6,
T = 10,
R = 15,
O = 21;
s = J(s);
C = e(s);
Y = 1732584193;
X = 4023233417;
W = 2562383102;
V = 271733878;
for (P = 0; P < C.length; P += 16) {
h = Y;
E = X;
v = W;
g = V;
Y = u(Y, X, W, V, C[P + 0], S, 3614090360);
V = u(V, Y, X, W, C[P + 1], Q, 3905402710);
W = u(W, V, Y, X, C[P + 2], N, 606105819);
X = u(X, W, V, Y, C[P + 3], M, 3250441966);
Y = u(Y, X, W, V, C[P + 4], S, 4118548399);
V = u(V, Y, X, W, C[P + 5], Q, 1200080426);
W = u(W, V, Y, X, C[P + 6], N, 2821735955);
X = u(X, W, V, Y, C[P + 7], M, 4249261313);
Y = u(Y, X, W, V, C[P + 8], S, 1770035416);
V = u(V, Y, X, W, C[P + 9], Q, 2336552879);
W = u(W, V, Y, X, C[P + 10], N, 4294925233);
X = u(X, W, V, Y, C[P + 11], M, 2304563134);
Y = u(Y, X, W, V, C[P + 12], S, 1804603682);
V = u(V, Y, X, W, C[P + 13], Q, 4254626195);
W = u(W, V, Y, X, C[P + 14], N, 2792965006);
X = u(X, W, V, Y, C[P + 15], M, 1236535329);
Y = f(Y, X, W, V, C[P + 1], A, 4129170786);
V = f(V, Y, X, W, C[P + 6], z, 3225465664);
W = f(W, V, Y, X, C[P + 11], y, 643717713);
X = f(X, W, V, Y, C[P + 0], w, 3921069994);
Y = f(Y, X, W, V, C[P + 5], A, 3593408605);
V = f(V, Y, X, W, C[P + 10], z, 38016083);
W = f(W, V, Y, X, C[P + 15], y, 3634488961);
X = f(X, W, V, Y, C[P + 4], w, 3889429448);
Y = f(Y, X, W, V, C[P + 9], A, 568446438);
V = f(V, Y, X, W, C[P + 14], z, 3275163606);
W = f(W, V, Y, X, C[P + 3], y, 4107603335);
X = f(X, W, V, Y, C[P + 8], w, 1163531501);
Y = f(Y, X, W, V, C[P + 13], A, 2850285829);
V = f(V, Y, X, W, C[P + 2], z, 4243563512);
W = f(W, V, Y, X, C[P + 7], y, 1735328473);
X = f(X, W, V, Y, C[P + 12], w, 2368359562);
Y = D(Y, X, W, V, C[P + 5], o, 4294588738);
V = D(V, Y, X, W, C[P + 8], m, 2272392833);
W = D(W, V, Y, X, C[P + 11], l, 1839030562);
X = D(X, W, V, Y, C[P + 14], j, 4259657740);
Y = D(Y, X, W, V, C[P + 1], o, 2763975236);
V = D(V, Y, X, W, C[P + 4], m, 1272893353);
W = D(W, V, Y, X, C[P + 7], l, 4139469664);
X = D(X, W, V, Y, C[P + 10], j, 3200236656);
Y = D(Y, X, W, V, C[P + 13], o, 681279174);
V = D(V, Y, X, W, C[P + 0], m, 3936430074);
W = D(W, V, Y, X, C[P + 3], l, 3572445317);
X = D(X, W, V, Y, C[P + 6], j, 76029189);
Y = D(Y, X, W, V, C[P + 9], o, 3654602809);
V = D(V, Y, X, W, C[P + 12], m, 3873151461);
W = D(W, V, Y, X, C[P + 15], l, 530742520);
X = D(X, W, V, Y, C[P + 2], j, 3299628645);
Y = t(Y, X, W, V, C[P + 0], U, 4096336452);
V = t(V, Y, X, W, C[P + 7], T, 1126891415);
W = t(W, V, Y, X, C[P + 14], R, 2878612391);
X = t(X, W, V, Y, C[P + 5], O, 4237533241);
Y = t(Y, X, W, V, C[P + 12], U, 1700485571);
V = t(V, Y, X, W, C[P + 3], T, 2399980690);
W = t(W, V, Y, X, C[P + 10], R, 4293915773);
X = t(X, W, V, Y, C[P + 1], O, 2240044497);
Y = t(Y, X, W, V, C[P + 8], U, 1873313359);
V = t(V, Y, X, W, C[P + 15], T, 4264355552);
W = t(W, V, Y, X, C[P + 6], R, 2734768916);
X = t(X, W, V, Y, C[P + 13], O, 1309151649);
Y = t(Y, X, W, V, C[P + 4], U, 4149444226);
V = t(V, Y, X, W, C[P + 11], T, 3174756917);
W = t(W, V, Y, X, C[P + 2], R, 718787259);
X = t(X, W, V, Y, C[P + 9], O, 3951481745);
Y = K(Y, h);
X = K(X, E);
W = K(W, v);
V = K(V, g)
}
var i = B(Y) + B(X) + B(W) + B(V);
return i.toLowerCase()
};
var size = size || 80;
return 'https://www.gravatar.com/avatar/' + MD5(email) + '.jpg?s=' + size;
}
Related
Maxima: eliminate variables from equations
Given N equations in K variables, can Maxima produce N-J equations in K-J variables? SOLVE and ELIMINATE seem unable, about to reach for pen and paper.
(%i1) elim ([a = x + y, b = y + z, c = z + x, a = b * c], [a, b, c]); (%o1) elim([a = y + x, b = z + y, c = z + x, a = b c], [a, b, c]) (%i2) load (to_poly); (%o2) ~/maxima-5.44.0/share/to_poly_solve/to_poly.lisp (%i3) elim ([a = x + y, b = y + z, c = z + x, a = b * c], [a, b, c]); 2 (%o3) [[z + (y + x) z + (x - 1) y - x], [b z - y + b x - x, z + x - c, y + x - a]] (%i4) solve (first (%o3), x); 2 z + y z - y (%o4) [x = - ------------] z + y - 1
Cartesian product in Dart Language
How can I create Cartesian Product of dynamic number of lists in Dart Language ? For example I have two lists: X: [A, B, C]; Y: [W, X, Y, Z] I want to create lists like this [AW, AX, AY, AZ, BW, BX, BY, BZ, CW, CX, CY, CZ] Although Python, Java have pre implemented libraries, there is none for Dart language I think.
Tested with Dart 2.5.0: class PermutationAlgorithmStrings { final List<List<String>> elements; PermutationAlgorithmStrings(this.elements); List<List<String>> permutations() { List<List<String>> perms = []; generatePermutations(elements, perms, 0, []); return perms; } void generatePermutations(List<List<String>> lists, List<List<String>> result, int depth, List<String> current) { if (depth == lists.length) { result.add(current); return; } for (int i = 0; i < lists[depth].length; i++) { generatePermutations(lists, result, depth + 1, [...current, lists[depth][i]]); } } } You can input any length of string arrays as you like. Use like this: PermutationAlgorithmStrings algo = PermutationAlgorithmStrings([ ["A", "B", "C"], ["W", "X", "Y", "Z"], ["M", "N"] ]); Output: output: [[A, W, M], [A, W, N], [A, X, M], [A, X, N], [A, Y, M], [A, Y, N], [A, Z, M], [A, Z, N], [B, W, M], [B, W, N], [B, X, M], [B, X, N], [B, Y, M], [B, Y, N], [B, Z, M], [B, Z, N], [C, W, M], [C, W, N], [C, X, M], [C, X, N], [C, Y, M], [C, Y, N], [C, Z, M], [C, Z, N]]
You can write this as a simple list: var product = [for (var x in X) for (var y in Y) "$x$y"]; (assuming X and Y contain strings and the combination you want is concatenation, otherwise write something else than "$x$y" to combine the x and y values). For an arbitrary number of lists, it gets more complicated. I'd probably prefer to generate the combinations lazily, instead of having to keep all the lists in memory at the same time if it isn't necessary. You can always create them eagerly if needed. Maybe try something like: Iterable<List<T>> cartesian<T>(List<List<T>> inputs) sync* { if (inputs.isEmpty) { yield List<T>(0); return; } var indices = List<int>.filled(inputs.length, 0); int cursor = inputs.length - 1; outer: do { yield [for (int i = 0; i < indices.length; i++) inputs[i][indices[i]]]; do { int next = indices[cursor] += 1; if (next < inputs[cursor].length) { cursor = inputs.length - 1; break; } indices[cursor] = 0; cursor--; if (cursor < 0) break outer; } while (true); } while (true); }
Functional solve. //declare type matters! List<List<dynamic>> cards = [ [1, 2, 3], [4, 5], ['x','y'] ]; cartesian product //or List flatten(List iterable) => iterable.expand((e) => e is List ? flatten(e) : [e]).toList(); // toList() cannot omit Iterable flatten(Iterable iterable) => iterable.expand((e) => e is Iterable ? flatten(e) : [e]); //cannot omit paramenter type List<List<dynamic>> cartesian(List<List<dynamic>> xs) => xs.reduce((List<dynamic> acc_x, List<dynamic> x) => // type cannot be omit acc_x.expand((i) => x.map((j) => flatten([i, j]).toList())).toList()); Maybe use Dart dynamic type is silly, you can use type friendly version I quit using reduce function because of its strict dimension limiting on parameters as well as returning values Type friendly List<List<T>> cartesian<T>(List<List<T>> list) { var head = list[0]; var tail = list.skip(1).toList(); List<List<T>> remainder = tail.length > 0 ? cartesian([...tail]) : [[]]; List<List<T>> rt = []; for (var h in head) { for (var r in remainder) rt.add([h, ...r]); } return rt; }
Try with this solution: void main() { List<String> a = ['A','B','C']; List<String> b = ['X','Y','Z']; List<String> c = a.map((ai) => b.map((bi) => ai+bi).toList()).expand((i) => i).toList(); c.forEach((ci) => print(ci)); }
Recurrence relation solution for relations with two interdependent variables
I came across the following problem in an online challenge. Consider the following vectors: x = [3, 4, ...] y = [2, 3, ...] Such that for i >= 2: x[i] = x[i-1] + 3 * y[i-2] y[i] = 2 * y[i-1] + 2 * x[i-2] What is x[10^15] ? While the problem has a very straightforward solution, the problem is the 10^15 value which cannot be calculated in a small time. Only thing I can think of is that we have to derive a polynomial from the recurrence relation - However this isn't easy to do. Am I missing something?
The problem statement can be express as matrix multiplication as follows: A= [ [1, 0, 0, 3], [1, 0, 0, 0], [0, 2, 2, 0], [0, 0, 1, 0] ] [xn+1, xn, yn+1, yn] = A*[xn, xn-1, yn, yn-1] => [xn+1, xn, yn+1, yn] = A^(n-1) * [x1, x0, y1, y0] [x1, x0, y1, y0] = [4, 3, 3, 2] While not mentioned in the problem, since the matrix multiplication exceeds integer limits, the solution needs to be expressed in as remainder of some prime number. Let the prime number be 1000000007. But how can we not exceed the integer limits while multiplying? Consider the following: (X * Y) mod p = ((X mod p) * (Y mod p)) mod p Now, X = A^n Let, A^n mod p = B Now, B = B mod p So, (X * Y) mod p = ((X mod p) * (Y mod p)) mod p => ((A^n mod p) * (Y mod p)) mod p => ( B * (Y mod p)) mod p => ((B mod p) * (Y mod p)) mod p => (B * Y) mod p So a simple python implementation would be: import numpy as np p = 1000000007 A= np.array([ [1, 0, 0, 3], [1, 0, 0, 0], [0, 2, 2, 0], [0, 0, 1, 0] ]) Y = np.array([4, 3, 3, 2]) # We will use binary exponentiation for fast matrix multiplication # See: https://cp-algorithms.com/algebra/binary-exp.html # The `power` list is the array of A's powers needed for that powers = [] powers.append(A % p) for i in range(1, 50): # Till 50 since 10^15 ~= 2^50 Ap = powers[i - 1] powers.append(Ap.dot(Ap) % p) def solve(n): pow_of_a = n - 3 index = 0 prod = np.identity(4) while (pow_of_a > 0): if (pow_of_a & 1) == 1: prod = prod.dot(powers[index]) pow_of_a >>= 1 index += 1 B = prod % p print(B.dot(Y) % p)
How to reduce memory useage when solving system of 9 coupled PDE
I have a system of coupled partial differential equations as shown in 1. system of equations If one writes the equations componentwise, one gets nine equations. For simplicity, one can set $\rho$ and $h$ constant. I put the equations into a mathematica notebook and used 'NDSolve'. I counted a number of 268 derivatives in the system. However, I didnt find more than 87 conditions that made sence. When I run the notebook, I get the message NDSolve::pdord: Some of the functions have zero differential order, so the equations will be solved as a system of differential-algebraic equations. >> LinearSolve::sing: Matrix SparseArray[Automatic,<<3>>] is singular. >> NDSolve::mconly: For the method IDA, only machine real code is available. Unable to continue with complex values or beyond floating-point exceptions. >> I understand the first error: There is no time derivative in $\phi$, so the system is strictly speaking a differential-algebraic-system. After about 40 minutes, mathematica says: No more memory available. Mathematica kernel has shut down. Try quitting other applications and then retry. What can I change to reduce the memory cost, or -- better -- what can I change to solve the system more elegant? Here is the mathematica code: NDSolve[{ eqn1 == 0, eqn2 == 0, eqn3 == 0, eqn4 == 0, eqn5 == 0, eqn6 == 0, eqn7 == 0, eqn8 == 0, eqn9 == 0, (*Initial Conditions*) T[0, x, y, z] == 300, p[0, x, y, z] == 101300, phi[t, x, y, z] == 75 x /. t -> 0, u1[0, x, y, z] == 0, (* ect... *) (*BOUNDARY CONDITIONS*) phi[t, x, y, z] == 0 /. x -> 0, phi[t, x, y, z] == 750 /. x -> 10, phi[t, x, y, z] == 75 x /. y -> 0, phi[t, x, y, z] == 75 x /. y -> 10, phi[t, x, y, z] == 75 x /. z -> 0, phi[t, x, y, z] == 75 x /. z -> 10, \!\( \*SubscriptBox[\(\[PartialD]\), \(y\)]\(phi[t, x, y, z]\)\) == 0 /. y -> 0, \!\( \*SubscriptBox[\(\[PartialD]\), \(y\)]\(phi[t, x, y, z]\)\) == 0 /. y -> 10, (* ect..... *) }, {p, u1, u2, u3, T, phi, a1, a2, a3}, {t, 0, 10}, {x, 0, 10}, {y, 0, 10}, {z, 0, 10} ] And here is the Latex-code for the equations: \begin{align} %%% first \frac{\partial \rho}{\partial t} + \vec{u} \cdot \nabla \rho + \rho \nabla \cdot \vec{u} &=0 \\ %%% second \rho \frac{\partial \vec{u}}{\partial t} + \rho \vec{u} \cdot \nabla \vec{u} \pm \nabla p + \nabla \cdot \left[- \mu \left( \nabla \vec{u} + \nabla \vec{u}^t \right) \right] \nonumber \\ - \left[ \sigma \left( - \nabla \phi - \frac{\partial \vec{A}}{\partial t} \right) + \vec{u} \times (\nabla \times \vec{A}) \right] % \times \left[ \nabla \times \vec{A} \right] &= \vec{0} \\ %%% third \rho \frac{\partial h}{\partial t} + \rho \vec{u} \cdot \nabla h + \nabla \cdot \nabla T - \frac{\partial p}{\partial t} - \overset{.}{Q_j} + \overset{.}{Q_r} &= 0 \\ %%% fourth \nabla \cdot \left[ \sigma \left( - \nabla \phi - \frac{\partial \vec{A}}{\partial t} \right) + \vec{u} \times (\nabla \times \vec{A}) \right] &= 0 \\ %%% fifth \frac{\partial \vec{A}}{\partial t} + \nabla \phi - \vec{u} \times \nabla \times \vec{A} - \eta \nabla ^2 \vec{A} &= \vec{0} \end{align} I add the plain mathematica code here: Needs["NDSolve`FEM`"] kB = N[ 8.6*10^-5 ]; AG = N[1.2*10^6 ]; mu0 = 1.257*10^(-6); sigma = N[20.]; eta = 1/(mu0 * sigma); rho = N[1.]; h = N[1672000.]; r = 1/ 287.058 ; mu = N[1.]; kappah = N[5.]; cp = N[2.4]; lbb = NDSolve[{ 0 == D[rho, t] + u1[t, x, y, z]*D[rho, x] + u2[t, x, y, z]*D[rho, y] + u3[t, x, y, z]*D[rho, z] + rho*(D[u1[t, x, y, z], x] + D[u2[t, x, y, z], y] + D[u3[t, x, y, z], z]), 0 == rho*D[u1[t, x, y, z], t] + rho*u1[t, x, y, z]*D[u1[t, x, y, z], x] - D[p[t, x, y, z], x] - mu*D[D[u1[t, x, y, z], x], x] - mu*D[D[u1[t, x, y, z], y], y] - mu*D[D[u1[t, x, y, z], z], z] - (((-sigma)*D[phi[t, x, y, z], y] - sigma*D[a2[t, x, y, z], t] + u3[t, x, y, z]*(D[a3[t, x, y, z], y] - D[a2[t, x, y, z], z]) - u1[t, x, y, z]*(D[a2[t, x, y, z], x] - D[a1[t, x, y, z], y]))*(D[ a2[t, x, y, z], x] - D[a1[t, x, y, z], y]) - ((-sigma)*D[phi[t, x, y, z], z] - sigma*D[a3[t, x, y, z], t] + u1[t, x, y, z]*(D[a1[t, x, y, z], z] - D[a3[t, x, y, z], x]) - u2[t, x, y, z]*(D[a3[t, x, y, z], y] - D[a2[t, x, y, z], z]))*(D[ a1[t, x, y, z], z] - D[a3[t, x, y, z], x])), 0 == rho*D[u2[t, x, y, z], t] + rho*u2[t, x, y, z]*D[u2[t, x, y, z], y] - D[p[t, x, y, z], y] - mu*D[D[u2[t, x, y, z], x], x] - mu*D[D[u2[t, x, y, z], y], y] - mu*D[D[u2[t, x, y, z], z], z] - (((-sigma)*D[phi[t, x, y, z], z] - sigma*D[a3[t, x, y, z], t] + u1[t, x, y, z]*(D[a1[t, x, y, z], z] - D[a3[t, x, y, z], x]) - u2[t, x, y, z]*(D[a3[t, x, y, z], y] - D[a2[t, x, y, z], z]))*(D[ a3[t, x, y, z], y] - D[a2[t, x, y, z], z]) - (D[a2[t, x, y, z], x] - D[a1[t, x, y, z], y])*((-sigma)*D[phi[t, x, y, z], x] - sigma*D[a1[t, x, y, z], t] + u2[t, x, y, z]*(D[a2[t, x, y, z], x] - D[a1[t, x, y, z], y]) - u3[t, x, y, z]*(D[a1[t, x, y, z], z] - D[a3[t, x, y, z], x]))), 0 == rho*D[u3[t, x, y, z], t] + rho*u3[t, x, y, z]*D[u3[t, x, y, z], z] - D[p[t, x, y, z], z] - mu*D[D[u3[t, x, y, z], x], x] - mu*D[D[u3[t, x, y, z], y], y] - mu*D[D[u3[t, x, y, z], z], z] - (((-sigma)*D[phi[t, x, y, z], x] - sigma*D[a1[t, x, y, z], t] + u2[t, x, y, z]*(D[a2[t, x, y, z], x] - D[a1[t, x, y, z], y]) - u3[t, x, y, z]*(D[a1[t, x, y, z], z] - D[a3[t, x, y, z], x]))*(D[ a1[t, x, y, z], z] - D[a3[t, x, y, z], x]) - ((-sigma)*D[phi[t, x, y, z], y] - sigma*D[a2[t, x, y, z], t] + u3[t, x, y, z]*(D[a3[t, x, y, z], y] - D[a2[t, x, y, z], z]) - u1[t, x, y, z]*(D[a2[t, x, y, z], x] - D[a1[t, x, y, z], y]))*(D[ a3[t, x, y, z], y] - D[a2[t, x, y, z], z])), 0 == rho*D[h, t] + rho*(u1[t, x, y, z]*D[h, x] + u2[t, x, y, z]*D[h, y] + u3[t, x, y, z]*D[h, z]) + kappah*(D[T[t, x, y, z], x, x] + D[D[T[t, x, y, z], y], y] + D[D[T[t, x, y, z], z], z]) - D[p[t, x, y, z], t], 0 == D[ sigma*(-D[phi[t, x, y, z], x] - D[a1[t, x, y, z], t]) + u2[t, x, y, z]*(D[a2[t, x, y, z], x] - D[a1[t, x, y, z], y]) - u3[t, x, y, z]*(D[a1[t, x, y, z], z] - D[a3[t, x, y, z], x]), x] + D[sigma*(-D[phi[t, x, y, z], y] - D[a2[t, x, y, z], t]) + u3[t, x, y, z]*(D[a3[t, x, y, z], y] - D[a2[t, x, y, z], z]) - u1[t, x, y, z]*(D[a2[t, x, y, z], x] - D[a1[t, x, y, z], y]), y] + D[sigma*(-D[phi[t, x, y, z], z] - D[a3[t, x, y, z], t]) + u1[t, x, y, z]*(D[a1[t, x, y, z], z] - D[a3[t, x, y, z], x]) - u2[t, x, y, z]*(D[a3[t, x, y, z], y] - D[a2[t, x, y, z], z]), z], 0 == D[a1[t, x, y, z], t] + D[phi[t, x, y, z], x] - u2[t, x, y, z]*(D[a2[t, x, y, z], x] - D[a1[t, x, y, z], y]) - u3[t, x, y, z]*(D[a1[t, x, y, z], z] - D[a3[t, x, y, z], x]) - eta*D[D[a1[t, x, y, z], x], x], 0 == D[a2[t, x, y, z], t] + D[phi[t, x, y, z], y] - u3[t, x, y, z]*(D[a3[t, x, y, z], y] - D[a2[t, x, y, z], z]) - u1[t, x, y, z]*(D[a2[t, x, y, z], x] - D[a1[t, x, y, z], y]) - eta*D[D[a2[t, x, y, z], y], y], 0 == D[a3[t, x, y, z], t] + D[phi[t, x, y, z], z] - u1[t, x, y, z]*(D[a1[t, x, y, z], z] - D[a3[t, x, y, z], x]) - u2[t, x, y, z]*(D[a3[t, x, y, z], y] - D[a2[t, x, y, z], z]) - eta*D[D[a3[t, x, y, z], z], z], T[0, x, y, z] == 300, p[0, x, y, z] == 101300, phi[t, x, y, z] == 75*x /. t -> 0, u1[0, x, y, z] == 0, u2[0, x, y, z] == 0, u3[0, x, y, z] == 0, a1[0, x, y, z] == 0, a2[0, x, y, z] == 0, a3[0, x, y, z] == 0, D[T[t, x, y, z], x] == 0 /. x -> 0, D[T[t, x, y, z], x] == 0 /. x -> 10, D[T[t, x, y, z], y] == 0 /. y -> 0, D[T[t, x, y, z], y] == 0 /. y -> 10, D[T[t, x, y, z], z] == 0 /. z -> 0, D[T[t, x, y, z], z] == 0 /. z -> 10, phi[t, x, y, z] == 0 /. x -> 0, phi[t, x, y, z] == 750 /. x -> 10, phi[t, x, y, z] == 75*x /. y -> 0, phi[t, x, y, z] == 75*x /. y -> 10, phi[t, x, y, z] == 75*x /. z -> 0, phi[t, x, y, z] == 75*x /. z -> 10, D[phi[t, 0, y, z], x] == (-sigma^(-1))*0.5*AG*T[t, 0, y, z]^2* Exp[-4/(kB*T[t, 0, y, z])], D[phi[t, 10, y, z], x] == (-sigma^(-1))*0.5*AG*T[t, 10, y, z]^2* Exp[-4/(kB*T[t, 10, y, z])], D[phi[t, x, y, z], y] == 0 /. y -> 0, D[phi[t, x, y, z], y] == 0 /. y -> 10, D[phi[t, x, y, z], z] == 0 /. z -> 0, D[phi[t, x, y, z], z] == 0 /. z -> 10, p[t, x, y, z] == 101300 /. x -> 0, p[t, x, y, z] == 101300 /. x -> 10, p[t, x, y, z] == 101300 /. y -> 0, p[t, x, y, z] == 101300 /. y -> 10, p[t, x, y, z] == 101300 /. z -> 0, p[t, x, y, z] == 101300 /. z -> 10, u1[t, x, y, z] == 0 /. x -> 0, u1[t, x, y, z] == 0 /. x -> 10, D[u1[t, x, y, z], y] == 0 /. y -> 0, D[u1[t, x, y, z], y] == 0 /. y -> 10, D[u1[t, x, y, z], z] == 0 /. z -> 0, D[u1[t, x, y, z], z] == 0 /. z -> 10, u2[t, x, y, z] == 0 /. x -> 0, u2[t, x, y, z] == 0 /. x -> 10, D[u2[t, x, y, z], y] == 0 /. y -> 0, D[u2[t, x, y, z], y] == 0 /. y -> 10, D[u2[t, x, y, z], z] == 0 /. z -> 0, D[u2[t, x, y, z], z] == 0 /. z -> 10, u3[t, x, y, z] == 0 /. x -> 0, u3[t, x, y, z] == 0 /. x -> 10, D[u3[t, x, y, z], y] == 0 /. y -> 0, D[u3[t, x, y, z], y] == 0 /. y -> 10, D[u3[t, x, y, z], z] == 0 /. z -> 0, D[u3[t, x, y, z], z] == 0 /. z -> 10, a1[t, x, y, z] == 0 /. x -> 0, a1[t, x, y, z] == 0 /. x -> 10, a1[t, x, y, z] == 0 /. y -> 0, a1[t, x, y, z] == 0 /. y -> 10, a1[t, x, y, z] == 0 /. z -> 0, a1[t, x, y, z] == 0 /. z -> 10, D[a1[t, x, y, z], x] == 0 /. x -> 0, D[a1[t, x, y, z], x] == 0 /. x -> 10, D[a1[t, x, y, z], y] == 0 /. y -> 0, D[a1[t, x, y, z], y] == 0 /. y -> 10, D[a1[t, x, y, z], z] == 0 /. z -> 0, D[a1[t, x, y, z], z] == 0 /. z -> 10, a2[t, x, y, z] == 0 /. x -> 0, a2[t, x, y, z] == 0 /. x -> 10, a2[t, x, y, z] == 0 /. y -> 0, a2[t, x, y, z] == 0 /. y -> 10, a2[t, x, y, z] == 0 /. z -> 0, a2[t, x, y, z] == 0 /. z -> 10, D[a2[t, x, y, z], x] == 0 /. x -> 0, D[a2[t, x, y, z], x] == 0 /. x -> 10, D[a2[t, x, y, z], y] == 0 /. y -> 0, D[a2[t, x, y, z], y] == 0 /. y -> 10, D[a2[t, x, y, z], z] == 0 /. z -> 0, D[a2[t, x, y, z], z] == 0 /. z -> 10, a3[t, x, y, z] == 0 /. x -> 0, a3[t, x, y, z] == 0 /. x -> 10, a3[t, x, y, z] == 0 /. y -> 0, a3[t, x, y, z] == 0 /. y -> 10, a3[t, x, y, z] == 0 /. z -> 0, a3[t, x, y, z] == 0 /. z -> 10, D[a3[t, x, y, z], x] == 0 /. x -> 0, D[a3[t, x, y, z], x] == 0 /. x -> 10, D[a3[t, x, y, z], y] == 0 /. y -> 0, D[a3[t, x, y, z], y] == 0 /. y -> 10, D[a3[t, x, y, z], z] == 0 /. z -> 0, D[a3[t, x, y, z], z] == 0 /. z -> 10 }, {p, u1, u2, u3, T, phi, a1, a2, a3}, {t, 0, 10}, {x, 0, 10}, {y, 0, 10}, {z, 0, 10}] Thanks a lot!
Divide a Point in Elliptic Curve Cryptography
I'm using Elliptic Curve to design a security system. P is a point on elliptic curve. The receiver must obtain P using formula k^-1(kP). The receiver does not know P but knows k. I need to compute k^-1(R) where R=kP. How can I do this using Point Multiplication or Point Addition.
I suggest first learning a bit more about ECC (for example, read some of Paar's book and listen to his course at http://www.crypto-textbook.com/) before tackling something this complex. For this particular question, ask yourself: "What does the inverse of k mean?"
Very interesting question you have! I was happy to implement from scratch Python solution for your task, see code at the bottom of my answer. Each elliptic curve has an integer order q. If we have any point P on curve then it is well known that q * P = Zero, in other words multiplying any point by order q gives zero-point (infinity point). Multiplying zero (infinity) point by any number gives zero again, i.e. j * Zero = Zero for any integer j. Adding any point P to zero-point gives P, i.e. Zero + P = P. In our task we have some k such that R = k * P. We can very easily (very fast) compute Modular Inverse of k modulo order q, using for example Extended Euclidean Algorithm. Inverse of k modulo q by definition is such that k * k^-1 = 1 (mod q), which by definition of modulus is equal k * k^-1 = j * q + 1 for some integer j. Then k^-1 * R = k^-1 * k * P = (j * q + 1) * P = j * (q * P) + P = j * Zero + P = Zero + P = P. Thus multiplying R by k^-1 gives P, if k^-1 is inverse of k modulo q. You can read about point addition and multiplication formulas on this Wiki. Lets now check our formulas in Python programming language. I decided to implement from scratch simple class ECPoint, which implements all curve operations (addition and multiplication), see code below. We take any ready-made curve, for example most popular 256-bit curve secp256k1, which is used in Bitcoin. Its parameters can be found here (this doc contains many other popular standard curves), also you can read about this specific curve on Bitcoin Wiki Page. Following code is fully self-contained Python script, doesn't need any external dependencies and modules. You can run it straight away on any computer. ECPoint class implements all curve arithmetics. Function test() does following operations: we take standard secp256k1 params with some base point G, we compute any random point P = random * G, then we generate random k, compute R = k * P, compute modular inverse k^-1 (mod q) by using function modular_inverse() (which uses extended Euclidean algorithm egcd()), compute found_P = k^-1 * R and check that it is equal to P, i.e. check that k^-1 * R == P, print resulting k^-1 * R. All random values are 256-bit. Try it online! def egcd(a, b): # https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm ro, r, so, s, to, t = a, b, 1, 0, 0, 1 while r != 0: ro, (q, r) = r, divmod(ro, r) so, s = s, so - q * s to, t = t, to - q * t return ro, so, to def modular_inverse(a, mod): # https://en.wikipedia.org/wiki/Modular_multiplicative_inverse g, s, t = egcd(a, mod) assert g == 1, 'Value not invertible by modulus!' return s % mod class ECPoint: #classmethod def Int(cls, x): return int(x) #classmethod def std_point(cls, name): if name == 'secp256k1': # https://en.bitcoin.it/wiki/Secp256k1 # https://www.secg.org/sec2-v2.pdf p = 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFC2F a = 0 b = 7 x = 0x79BE667E_F9DCBBAC_55A06295_CE870B07_029BFCDB_2DCE28D9_59F2815B_16F81798 y = 0x483ADA77_26A3C465_5DA4FBFC_0E1108A8_FD17B448_A6855419_9C47D08F_FB10D4B8 q = 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_BAAEDCE6_AF48A03B_BFD25E8C_D0364141 else: assert False return ECPoint(x, y, a, b, p, q) def __init__(self, x, y, A, B, N, q, *, prepare = True): if prepare: N = self.Int(N) A, B, x, y, q = [self.Int(e) % N for e in [A, B, x, y, q]] assert (4 * A ** 3 + 27 * B ** 2) % N != 0 assert (y ** 2 - x ** 3 - A * x - B) % N == 0, ( x, y, A, B, N, (y ** 2 - x ** 3 - A * x) % N) assert N % 4 == 3 assert y == pow(x ** 3 + A * x + B, (N + 1) // 4, N) self.A, self.B, self.N, self.x, self.y, self.q = A, B, N, x, y, q def __add__(self, other): A, N = self.A, self.N Px, Py, Qx, Qy = self.x, self.y, other.x, other.y if Px == Qx and Py == Qy: s = ((Px * Px * 3 + A) * self.inv(Py * 2, N)) % N else: s = ((Py - Qy) * self.inv(Px - Qx, N)) % N x = (s * s - Px - Qx) % N y = (s * (Px - x) - Py) % N return ECPoint(x, y, A, self.B, N, self.q, prepare = False) def __rmul__(self, other): other = self.Int(other - 1) r = self while True: if other & 1: r = r + self if other == 1: return r other >>= 1 self = self + self #classmethod def inv(cls, a, n): return modular_inverse(a, n) def __repr__(self): return str(dict(x = self.x, y = self.y, A = self.A, B = self.B, N = self.N, q = self.q)) def __eq__(self, other): for i, (a, b) in enumerate([ (self.x, other.x), (self.y, other.y), (self.A, other.A), (self.B, other.B), (self.N, other.N), (self.q, other.q)]): if a != b: return False return True def test(): import random bits = 256 P = random.randrange(1 << bits) * ECPoint.std_point('secp256k1') k = random.randrange(1 << bits) R = k * P found_P = modular_inverse(k, R.q) * R assert found_P == P print(found_P) if __name__ == '__main__': test() Output: { 'x': 108051465657467150531748691374311160382608428790397210924352716318223953013557, 'y': 4462548165448905789984443302412298811224817997977472205419179335194291964455, 'A': 0, 'B': 7, 'N': 115792089237316195423570985008687907853269984665640564039457584007908834671663, 'q': 115792089237316195423570985008687907852837564279074904382605163141518161494337 }