JavaScript (ES6), 62 61 60 bytes
My Python port, ported back to JS. :-p
f=(n,k,o=k%2)=>n--?k-5&&(2-o)*f(n,!k*3-~o)+(k&5&&f(n,o*4)):1
Try it online!
Below is my original 62-byte version, which is easier to understand:
f=(n,k)=>n--?k&1?k-5&&f(n,2)+f(n,4):2*f(n,k?1:4)+(k&4&&f(n)):1
Try it online!
How?
There are 4 groups of keys which are really connected together. All keys within a group have the exact same behavior.
- Corners 1, 3, 7, 9 (in green). Characterization: odd keys that are not equal to \$5\$.
- Left/right sides 4, 6 (in blue). Characterization: even keys for which we have \$k \operatorname{and}4 = 4\$.
- Top/bottom sides 2, 8 (in yellow). Characterization: non-zero even keys for which we have \$k \operatorname{and}4 = 0\$.
- The 0 key (in red).
The 5 key is secluded and processed separately.
The figure on the right is a weighted directed graph showing which target groups can be reached from a given source group, and how many distinct keys are valid targets within each target group.
This algorithm does one recursive call per target group from the current group, multiplies each result by the corresponding weight and sums them all.
Only the first iteration is expecting \$k\in[0..9]\$. For the next ones, we just set \$k\$ to the leading key of each group (\$1\$, \$4\$, \$2\$ and \$0\$ respectively).
JavaScript (ES6), 86 74 72 bytes
f=(p,n,k=10)=>n?k--&&(306>>(p*2149^k*2149)%71%35&1&&f(k,n-1))+f(p,n,k):1
Try it online!
71 bytes
Much, much slower.
f=(p,n,k=10)=>n?k--&&(306>>(p*2149^k*2149)%71%35&1)*f(k,n-1)+f(p,n,k):1
Try it online!
Finding a hash function
We are looking for a function \$h(p,k)\$ telling whether \$p\$ and \$k\$ are connected by a knight hop. Because this function is commutative and because the result is always the same when \$p=k\$, a bitwise XOR looks like a good candidate.
We can't directly do \$p \operatorname{XOR} k\$ because, for instance, \$0 \operatorname{XOR} 4\$ and \$3 \operatorname{XOR} 7\$ are both equal to \$4\$ although \$(0,4)\$ are connected and \$(3,7)\$ are not.
We need to get more entropy by applying some multiplier \$M\$ such that \$(M\times p)\operatorname{XOR}\:(M\times k)\$ is collision-free. The first few valid multipliers are \$75\$, \$77\$, \$83\$, ... (We could apply two distinct multipliers to \$p\$ and \$k\$, but we would lose the benefit of the function being commutative. So it's unlikely to lead to a smaller expression.)
For each valid multiplier, we then look for some modulo chain to reduce the size of the lookup table.
By running a brute-force search with \$M<10000\$ and two modulos \$1<m_0<m_1<100\$ followed by a modulo \$32\$, the following expression arises:
$$h(p,k)=((((p\times 2149)\operatorname{XOR}\:(k\times 2149))\bmod 71)\bmod 35)\bmod 32$$
We have a valid hop iff \$h(p,k)\in\{1,4,5,8\}\$, which can be represented as the small bit-mask \$100110010_2=306_{10}\$.
Hence the JS implementation:
306 >> (p * 2149 ^ k * 2149) % 71 % 35 & 1
Note that the final modulo \$32\$ is implicitly provided by the right-shift.
Commented
f = ( // f is a recursive function taking:
p, // p = current position
n, // n = number of remaining hops
k = 10 // k = key counter
) => //
n ? // if n is not equal to 0:
k-- && ( // decrement k; if it was not 0:
306 >> // right-shifted lookup bit-mask
(p * 2149 ^ k * 2149) // apply the XOR
% 71 % 35 // apply the modulo chain
& 1 && // if the least significant bit is set:
f(k, n - 1) // do a recursive call with p = k and n - 1
) + //
f(p, n, k) // add the result of a recursive call
// with the updated k
: // else:
1 // stop the recursion
// and increment the final result